处理返回匿名方法的方法
本文关键字:方法 返回 处理 | 更新日期: 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);
});