I'm hoping someone can identify the language feature (or bug) that resulted in the change in behaviour of the program below. It is reproduced from a much larger scenario that was intended to log a message if the delegate supplied to Orchard::Go was not static.
using System;
namespace Sample
{
public static class Program
{
public static void Main()
{
new Apple();
}
}
public sealed class Apple
{
public Apple()
{
Orchard.Go(() => { });
}
}
internal static class Orchard
{
public static void Go(Action action)
{
Console.WriteLine(action.Method.IsStatic);
}
}
}
The scenario is:
- If I compile and run a debug build produced with Visual Studio 2013, the output is True.
- If I compile and run a debug build produced with Visual Studio 2015, the output is False.
- In both cases, the target .NET Framework is 4.5.
- If I compile and run a release build produced with Visual Studio 2015, the output is True (and thus consistent with Visual Studio 2013).
- Visual Studio 2015 is the RC version (if that matters).
I can see from ildasm the 2013 generated code...
___[MOD] C:\Sample.exe
| M A N I F E S T
|___[NSP] Sample
| |___[CLS] Sample.Apple
| | | .class public auto ansi sealed beforefieldinit
| | |___[STF] CS$9__CachedAnonymousMethodDelegate1 : private static class [mscorlib]System.Action
| | |___[MET] .ctor : void()
| | | b__0 : void()
| |
| |___[CLS] Sample.Orchard
| | | .class private abstract auto ansi sealed beforefieldinit
| | |___[STM] Go : void(class [mscorlib]System.Action)
| |
| |___[CLS] Sample.Program
| | | .class public abstract auto ansi sealed beforefieldinit
| | |___[STM] Main : void()
| |
|
...is clearly different to the 2015 generated code...
___[MOD] C:\Sample.exe
| M A N I F E S T
|___[NSP] Sample
| |___[CLS] Sample.Apple
| | | .class public auto ansi sealed beforefieldinit
| | |___[CLS] c
| | | | .class nested private auto ansi serializable sealed beforefieldinit
| | | | .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) ...
| | | |___[STF] 9 : public static initonly class Sample.Apple/'c'
| | | |___[STF] 9__0_0 : public static class [mscorlib]System.Action
| | | |___[STM] .cctor : void()
| | | |___[MET] .ctor : void()
| | | | b__0_0 : void()
| | |
| | |___[MET] .ctor : void()
| |
| |___[CLS] Sample.Orchard
| | | .class private abstract auto ansi sealed beforefieldinit
| | |___[STM] Go : void(class [mscorlib]System.Action)
| |
| |___[CLS] Sample.Program
| | | .class public abstract auto ansi sealed beforefieldinit
| | |___[STM] Main : void()
| |
|
...but my knowledge of IL and compiler changes isn't sufficient to determine whether this is a new feature or an unintended bug. I can produce the full IL dumps on request, but can anyone tell me from the information I've supplied what is going on here and whether it is intentional? Why is the anonymous method considered static in 2013 but non-static in 2015?