鉴于以下控制台程序:
class Program
{
private static string _value;
static void Main(string[] args)
{
var t = new Action(() => _value = "foo");
Console.Out.WriteLine("t.Method.IsStatic: {0}", t.Method.IsStatic);
}
}
使用VS 2013编译.Net 4.5.2时,将打印
t.Method.IsStatic: true
使用VS 2015针对.Net 4.5.2进行编译时,将打印
t.Method.IsStatic: false
从this问题,我有点理解发生了什么,但我很困惑为什么VS版本之间的行为发生了变化。根据我的理解,2013年的输出是正确的。
答案 0 :(得分:4)
在以下链接中查看答案: Delegate caching behavior changes in Roslyn
基本上改变了什么,我从链接的答案引用@Yuzal:
" Roslyn中的代理缓存行为已更改。以前,作为 声明,任何没有捕获变量的lambda表达式都是 在调用站点编译成静态方法。罗斯林改变了这个 行为。现在,任何捕获变量与否的lambda都是 变成了一个展示类:"
通过显示类,他指的是一个生成的私有密封类,其中封装了动作委托调用的实例方法。
为何进行了更改?引用@Kevin Pilch-Bisson(C#IDE团队成员):
它更快的原因是因为委托调用被优化了 实例方法并为它们在堆栈上留出空间。打电话给 静态方法,他们必须改变参数。
所以基本上评论是自我解释的。您在上面的示例中看到的行为差异是因为他们注意到,如果Action委托调用实例方法比调用静态方法更快,无论lambda是否捕获变量。
答案 1 :(得分:0)
从this开始,2013年编译器和Rosyln之间的行为发生了变化。非常烦人。