为什么 Action.Method.IsStatic 在 Visual Studio 2013 和 2015 之间对于某些 lambda 表达式不同
Why is Action.Method.IsStatic different between Visual Studio 2013 and 2015 for certain lambda expressions
给定以下控制台程序:
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 年的输出是正确的。
从 this 看来,行为在 2013 编译器和 Rosyln 之间发生了变化。很烦人。
检查以下 link 中的答案:
基本上发生了什么变化,我从 linked 的回答中引用@Yuzal:
"Delegate caching behavior was changed in Roslyn. Previously, as
stated, any lambda expression which didn't capture variables was
compiled into a static method at the call site. Roslyn changed this
behavior. Now, any lambda, which captures variables or not, is
transformed into a display class:"
他所说的显示 class 是指生成的私有密封 class,其中封装了动作委托调用的实例方法。
为什么要进行更改?引用 @Kevin Pilch-Bisson(C# IDE 团队的成员):
The reason it's faster is because delegate invokes are optimized for
instance methods and have space on the stack for them. To call a
static method they have to shift parameters around.
所以评论基本上是不言自明的。您在上面的示例中看到的行为差异是因为他们注意到如果 Action 委托调用实例方法比调用静态方法更快,无论 lambda 是否捕获变量。
给定以下控制台程序:
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 年的输出是正确的。
从 this 看来,行为在 2013 编译器和 Rosyln 之间发生了变化。很烦人。
检查以下 link 中的答案:
基本上发生了什么变化,我从 linked 的回答中引用@Yuzal:
"Delegate caching behavior was changed in Roslyn. Previously, as stated, any lambda expression which didn't capture variables was compiled into a static method at the call site. Roslyn changed this behavior. Now, any lambda, which captures variables or not, is transformed into a display class:"
他所说的显示 class 是指生成的私有密封 class,其中封装了动作委托调用的实例方法。
为什么要进行更改?引用 @Kevin Pilch-Bisson(C# IDE 团队的成员):
The reason it's faster is because delegate invokes are optimized for instance methods and have space on the stack for them. To call a static method they have to shift parameters around.
所以评论基本上是不言自明的。您在上面的示例中看到的行为差异是因为他们注意到如果 Action 委托调用实例方法比调用静态方法更快,无论 lambda 是否捕获变量。