处理返回匿名方法的方法

本文关键字:方法 返回 处理 | 更新日期: 2023-09-27 18:09:38

如果我有这样一个类:

public class SomeClass
{
    public Action<string> SomeAction { get; set; }
    public SomeClass()
    {
        SomeAction = GetSomeAnonymousMethod();
    }
    private Action<string> GetSomeAnonymousMethod()
    {
        return (text) =>
        {
            Console.WriteLine(text);
        };
    }
}

当我创建一个新的SomeClass实例时会发生什么?我的印象是构造函数简单地调用GetSomeAnonymousMethod(),它返回一个新的委托实例(它只包含对编译器生成的匿名方法的支持方法的引用),并将其分配给SomeAction属性。

有人能证实吗,还是发生了更险恶的事情?

处理返回匿名方法的方法

好吧,这就是所发生的一切。在这种特殊情况下,您的lambda表达式(它不是一个匿名方法)不需要任何状态,因此生成的方法可以是静态的,并且可以缓存委托引用。所以"new delegate instance"部分可能不是正确的。

所以更像这样——至少在用MS编译器编译时:

public class SomeClass
{
    private static Action<string> cachedAction;
    public Action<string> SomeAction { get; set; }
    public SomeClass()
    {
        SomeAction = GetSomeAnonymousMethod();
    }
    private Action<string> GetSomeAnonymousMethod()
    {
        Action<string> action = cachedAction;
        if (action == null)
        {
            action = AnonymousMethodImplementation;
            cachedAction = action;
        }
        return action;
    }
    private static void AnonymousMethodImplementation(string text)
    {
        Console.WriteLine(text);
    }
}

你不需要担心这些细节——这都是一个实现细节…只是做了一点优化。但如果你真的想知道发生了什么,那更接近现实。

与以往一样,要查看编译器正在做什么的细节,您可以始终使用ildasm(例如,IL模式下的Reflector)并查看生成的IL。

有人能证实吗,还是发生了更险恶的事情?

这似乎是新冷战和第二次冷战事件中的另一个秘密行动!

是的,你的构造函数正在做你在问题中描述的事情。

我会解释匿名委托使用委托类型推断转换为Action<string>

例如,以下代码行:

return (text) =>
        {
            Console.WriteLine(text);
        };

…被推断为:

return new Action<string>((text) => 
{
     Console.WriteLine(text);
});