6

Consider the following example code.

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 );
    }
}

If I compile and run this code under Debug using the Visual Studio 2010 (under CSC compiler) it will print out the following result:

Method is not static.
Value: 5

If I compile the same code in Visual Studio 2010, but this time using Release settings, the following output will be generated:

Method is static.
Value: 5

Now, if we were to execute the same code but this time using Visual Studio 2015 CTP (under the Roslyn compiler), the following output is generated for both Debug and Release settings:

Method is not static.
Value: 5

First, I find it curious that there is a difference between the Debug and Release versions of VS2010 (CSC). Why would it not evaluate as a static method under debug? Also, it appears that under some cases it does evaluate as static when compiled in Debug. I have a production application that is getting the expected static result under Debug.

Secondly, should the Roslyn compiler match the behavior of CSC in this particular case?

deloreyk
  • 1,248
  • 15
  • 24
  • 1
    The IL has no concept of lambdas. Lambdas are compiled to anonymous type. As the linked question shows, the compiler may generate static methods if no closures are involved. Your code shouldn't depend on such behaviour though, it's strictly a matter of compiler implementation and optimizations – Panagiotis Kanavos Jul 14 '15 at 14:33
  • 2
    @PanagiotisKanavos Yes, I understand why and agree with you that the code should not depend on that behavior, it is just something that I found and I was curious of the difference. I do not agree that this question was a duplicate of the linked question. My question understands that it may make methods static if no closures exist. My question was basically asking why the Roslyn compiler would choose not to do this at all. – deloreyk Jul 14 '15 at 14:39
  • See https://roslyn.codeplex.com/workitem/246, which explains why this change was made. – SLaks Jul 14 '15 at 15:50

1 Answers1

12

This was a deliberate change made by the Roslyn team.

Delegates that point to instance methods are slightly faster to invoke, so Roslyn now compiles lambdas to instance methods even when it doesn't need to.

See discussion.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964