如果我有这样的课程:
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
属性。
有人可以确认,还是更险恶的事情?
答案 0 :(得分:2)
嗯,几乎所有发生的事情。在这种特殊情况下,你的lambda表达式(它不是一个匿名方法,挑剔)不需要任何状态,因此生成的方法可以是静态的,并且可以缓存委托引用。所以&#34;新代表实例&#34;部分可能不是正确的。
所以它的更多就像这样 - 至少在使用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。
答案 1 :(得分:1)
有人可以确认,还是更险恶的事情?
这似乎是新冷战和第二次冷战事件中的另一个秘密行动!
是的,您的构造函数正在执行您在问题中描述的内容。
我会解释使用delegate type inference将匿名委托转换为Action<string>
。
例如,以下代码行:
return (text) =>
{
Console.WriteLine(text);
};
......感谢:
return new Action<string>((text) =>
{
Console.WriteLine(text);
});