That sure looks like a bug. Thanks for bringing it to my attention. I'll look into it. It is possible that it has already been found and fixed.
It seems to be a bug or unnecessary:
I run you exemple in IL lang:
.method public hidebysig
instance void InstanceMethod () cil managed
{
// Method begins at RVA 0x2074
// Code size 63 (0x3f)
.maxstack 4
.locals init (
[0] class ConsoleApplication1.Program/Foo/'<>c__DisplayClass1' 'CS$<>8__locals2'
)
IL_0000: newobj instance void ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: ldarg.0
IL_0008: stfld class ConsoleApplication1.Program/Foo ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::'<>4__this' //Make ref to this
IL_000d: nop
IL_000e: ldloc.0
IL_000f: ldc.r8 42
IL_0018: ldc.r8 1
IL_0021: call float64 [mscorlib]System.Math::Pow(float64, float64)
IL_0026: stfld float64 ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::capturedVariable
IL_002b: ldarg.0
IL_002c: ldloc.0
IL_002d: ldftn instance void ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::'<InstanceMethod>b__0'()
IL_0033: newobj instance void [mscorlib]System.Action::.ctor(object, native int)
IL_0038: stfld class [mscorlib]System.Action ConsoleApplication1.Program/Foo::_field
IL_003d: nop
IL_003e: ret
} // end of method Foo::InstanceMethod
Example 2:
class Program
{
static void Main(string[] args)
{
}
class Foo
{
private Action _field;
public void InstanceMethod()
{
var capturedVariable = Math.Pow(42, 1);
_field = () => Foo2.StaticMethod(capturedVariable); //Foo2
}
private static void StaticMethod(double arg) { }
}
class Foo2
{
internal static void StaticMethod(double arg) { }
}
}
in cl: (Note !! now the this reference is gone !)
public hidebysig
instance void InstanceMethod () cil managed
{
// Method begins at RVA 0x2074
// Code size 56 (0x38)
.maxstack 4
.locals init (
[0] class ConsoleApplication1.Program/Foo/'<>c__DisplayClass1' 'CS$<>8__locals2'
)
IL_0000: newobj instance void ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::.ctor()
IL_0005: stloc.0
IL_0006: nop //No this pointer
IL_0007: ldloc.0
IL_0008: ldc.r8 42
IL_0011: ldc.r8 1
IL_001a: call float64 [mscorlib]System.Math::Pow(float64, float64)
IL_001f: stfld float64 ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::capturedVariable
IL_0024: ldarg.0 //No This ref
IL_0025: ldloc.0
IL_0026: ldftn instance void ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::'<InstanceMethod>b__0'()
IL_002c: newobj instance void [mscorlib]System.Action::.ctor(object, native int)
IL_0031: stfld class [mscorlib]System.Action ConsoleApplication1.Program/Foo::_field
IL_0036: nop
IL_0037: ret
}
Exemple 3:
class Program
{
static void Main(string[] args)
{
}
static void Test(double arg)
{
}
class Foo
{
private Action _field;
public void InstanceMethod()
{
var capturedVariable = Math.Pow(42, 1);
_field = () => Test(capturedVariable);
}
private static void StaticMethod(double arg) { }
}
}
in IL: (This pointer is back)
IL_0006: ldloc.0
IL_0007: ldarg.0
IL_0008: stfld class ConsoleApplication1.Program/Foo ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::'<>4__this' //Back again.
And in all three cases the method-b__0() - look the same:
instance void '<InstanceMethod>b__0' () cil managed
{
// Method begins at RVA 0x2066
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld float64 ConsoleApplication1.Program/Foo/'<>c__DisplayClass1'::capturedVariable
IL_0006: call void ConsoleApplication1.Program/Foo::StaticMethod(float64) //Your example
IL_0006: call void ConsoleApplication1.Program/Foo2::StaticMethod(float64)//Example 2
IL_0006: call void ConsoleApplication1.Program::Test(float64) //Example 3
IL_000b: nop
IL_000c: ret
}
And in all 3 cases there is an reference to an static method, so it makes it more odd. So after this litle analys, i will say its an bug / for no good. !
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