CSC和Roslyn编译器在静态lambda表达式求值方面有什么区别?

6
考虑以下示例代码。
class Program
{
    static void Main( string[] args )
    {
        DoSomethingWithAction( i =>
            {
                Console.WriteLine( "Value: {0}", i );
            } );

        Console.ReadLine();
    }

    private static void DoSomethingWithAction( Action<int> something )
    {
        Console.WriteLine( something.Target == null
            ? "Method is static."
            : "Method is not static." );

        something( 5 );
    }
}

如果我在使用Visual Studio 2010(使用CSC编译器)的Debug模式下编译和运行此代码,它将打印出以下结果:
Method is not static.
Value: 5

如果我使用Visual Studio 2010编译相同的代码,但这次使用Release设置,则会生成以下输出:

Method is static.
Value: 5

现在,如果我们使用Visual Studio 2015 CTP(在Roslyn编译器下)执行相同的代码,则对于DebugRelease设置,将生成以下输出:

Method is not static.
Value: 5

首先,我发现在VS2010(CSC)的Debug和Release版本之间存在差异是很奇怪的。为什么在Debug下它不能作为一个静态方法来评估呢?此外,似乎在某些情况下,在Debug中编译后它会被评估为静态的。我有一个正在生产中应用程序在Debug下得到了预期的静态结果。

其次,Roslyn编译器是否应该匹配CSC在这种特定情况下的行为?


1
IL没有lambda的概念。Lambda被编译为匿名类型。正如链接的问题所示,如果没有涉及到闭包,编译器可能会生成静态方法。但是你的代码不应该依赖这种行为,因为它严格是编译器实现和优化的问题。 - Panagiotis Kanavos
2
@PanagiotisKanavos 是的,我理解并同意你的观点,代码不应该依赖于那种行为,只是我发现了这个问题,对差异感到好奇。我不认为这个问题是链接问题的副本。我的问题理解如果没有闭包,则可以将方法静态化。我的问题基本上是在问为什么Roslyn编译器根本不选择这样做。 - deloreyk
请参见 https://roslyn.codeplex.com/workitem/246,该页面解释了为什么进行了此更改。 - SLaks
1个回答

12

这是Roslyn团队有意进行的更改。

指向实例方法的委托调用速度稍快,因此即使Roslyn不需要,现在也将Lambda编译为实例方法。

请参见讨论


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接