为什么Action.Method.IsStatic对于某些lambda表达式

时间:2016-05-11 03:48:19

标签: c# visual-studio-2013 visual-studio-2015 roslyn

鉴于以下控制台程序:

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年的输出是正确的。

2 个答案:

答案 0 :(得分:4)

在以下链接中查看答案: Delegate caching behavior changes in Roslyn

基本上改变了什么,我从链接的答案引用@Yuzal:

  

" Roslyn中的代理缓存行为已更改。以前,作为   声明,任何没有捕获变量的lambda表达式都是   在调用站点编译成静态方法。罗斯林改变了这个   行为。现在,任何捕获变量与否的lambda都是   变成了一个展示类:"

通过显示类,他指的是一个生成的私有密封类,其中封装了动作委托调用的实例方法。

为何进行了更改?引用@Kevin Pilch-Bisson(C#IDE团队成员):

  

它更快的原因是因为委托调用被优化了   实例方法并为它们在堆栈上留出空间。打电话给   静态方法,他们必须改变参数。

所以基本上评论是自我解释的。您在上面的示例中看到的行为差异是因为他们注意到,如果Action委托调用实例方法比调用静态方法更快,无论lambda是否捕获变量。

答案 1 :(得分:0)

this开始,2013年编译器和Rosyln之间的行为发生了变化。非常烦人。