Given the below console program:
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);
}
}
When compiled against .Net 4.5.2 using VS 2013, it will print
t.Method.IsStatic: true
When compiled against .Net 4.5.2 using VS 2015, it will print
t.Method.IsStatic: false
From this question, I kind of understand what is happening, but I'm confused why there is a change in behavior between versions of VS. From my understanding, the 2013 output is correct.
Check the answer in the following link : Delegate caching behavior changes in Roslyn
Basically what changed and i quote @Yuzal from the linked answer :
"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:"
And by display class he meant a generated private sealed class within which encapsulates the instance method invoked by the action delegate.
Why the change was made ? Quoting @Kevin Pilch-Bisson (a member of the C# IDE team) :
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.
So basically the comment is self explanatory. The behaviour difference you see in the example above is because they noticed that if the Action delegate invoked instance methods its faster than invoking static methods regardless if the lambda captures variables or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With