我使用dotPeek深入了解C#编译器魔术,反编译代码中的某些内容引起了我的注意。我正在创建一个Action<int>
实例并将其传递给Start()
方法,编译器会生成以下内容:
new Program().Start(new Action<int>((object) cDisplayClass1, __methodptr(<Main>b__0)));
我一般都明白这里发生了什么,我唯一的问题是什么是__methodptr?确切地说,它来自哪里?是IL吗? dotPeek并不知道它或包含它的程序集。谷歌也没有提供准确的答案,只提供相同的代码片段,没有任何解释。
谢谢!
答案 0 :(得分:2)
__ methodptr 对应IL指令 ldftn ,粗略地说 ldftn 将“函数指针”加载到评估堆栈上。这是一个样本:
已解压缩的来源:
private static void Main(string[] args)
{
Program.\u003C\u003Ec__DisplayClass0_0 cDisplayClass00 = new Program.\u003C\u003Ec__DisplayClass0_0();
cDisplayClass00.xx = 100;
// ISSUE: method pointer
new Action((object) cDisplayClass00, __methodptr(\u003CMain\u003Eb__0))();
Console.WriteLine(cDisplayClass00.xx);
}
IL:
1个加载函数指针类::方法
IL_000f: ldloc.0 // cDisplayClass00
IL_0010: ldftn instance void TestIL.Program/'<>c__DisplayClass0_0'::'<Main>b__0'()
2新的委托传递对象和函数指针
IL_0016: newobj instance void [mscorlib]System.Action::.ctor(object, native int)
IL_001b: stloc.1 // V_1
3呼叫代表
IL_001c: ldloc.1 // V_1
IL_001d: callvirt instance void [mscorlib]System.Action::Invoke()
IL_0022: nop
答案 1 :(得分:0)
您应该按如下方式替换代码:
new Action(cDisplayClass00.Mainb__0))();
可以这么说,函数指针指向自动生成类上的自动生成方法。