对于某些lambda表达式,为什么Action.Method.IsStatic在Visual Studio 2013和2015之间有所不同

Mat*_*ttS 5 c# roslyn visual-studio-2013 visual-studio-2015

鉴于以下控制台程序:

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);
    } 
}
Run Code Online (Sandbox Code Playgroud)

当使用VS 2013针对.Net 4.5.2编译时,它将打印出来

t.Method.IsStatic: true
Run Code Online (Sandbox Code Playgroud)

当使用VS 2015针对.Net 4.5.2编译时,它将打印出来

t.Method.IsStatic: false
Run Code Online (Sandbox Code Playgroud)

这个问题,我有点理解发生了什么,但我很困惑为什么VS的版本之间的行为发生了变化.根据我的理解,2013年的输出是正确的.

Sir*_*our 4

检查以下链接中的答案: Roslyn 中的委托缓存行为更改

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

“Roslyn 中的委托缓存行为已更改。之前,如前所述,任何未捕获变量的 lambda 表达式都会在调用站点编译为静态方法。Roslyn 更改了此行为。现在,任何 lambda,无论是否捕获变量,转化为显示类:”

他所说的显示类是指生成的私有密封类,其中封装了由操作委托调用的实例方法。

为什么要做出这样的改变?引用@Kevin Pilch-Bisson(C# IDE 团队成员):

它更快的原因是因为委托调用针对实例方法进行了优化,并且在堆栈上为它们提供了空间。要调用静态方法,他们必须移动参数。

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