4

我想使用System.Reflection.Emit命名空间为二维数组构造生成 IL。

我的 C# 代码是

Array 2dArr  = Array.CreateInstance(typeof(int),100,100); 

使用ildasm,我意识到为上述 C# 代码生成了以下 IL 代码。

IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b:  ldc.i4.s   100
IL_000d:  ldc.i4.s   100
IL_000f:  call       class [mscorlib]System.Array [mscorlib]System.Array::CreateInstance(class [mscorlib]System.Type, 
                                                                                           int32,
                                                                                           int32)

我能够生成最后三个 IL 语句,如下所示。

MethodInfo createArray = typeof(Array).GetMethod("CreateInstance",
                new Type[] { typeof(Type),typeof(int),typeof(int) });
gen.Emit(OpCodes.Ldc_I4_1);
           gen.Emit(OpCodes.Ldc_I4_1);
           gen.Emit(OpCodes.Call, createArray);

但我对如何生成第一个 IL 语句(即IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)没有明确的想法)

你有什么主意吗?

此外,有人可以提出一些关于如何使用 System.Reflection.Emit 命名空间来生成 IL 代码的好教程/文档吗?

4

1 回答 1

8

啊,很好' typeof; 对,是:

 il.Emit(OpCodes.Ldtoken, typeof(int));
 il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);

重新指导......如果我遇到困难,我的诀窍总是“编译类似的东西,然后在反射器中查看它”。

如果你想要一些例子dapper-dot-netprotobuf-net都做了相当多的 IL - 第一个更包含、有限和易于理解;第二个是全力以赴、无拘无束的疯狂 IL。

IL的提示:

  • 在屏幕右侧的每一步的评论中跟踪堆栈
  • 使用分支等的缩写形式,但只有在你知道你有一个非常本地的分支时才使用它们
  • 为自己写一些实用方法,即使是简单的事情,比如加载一个整数(这实际上非常复杂,因为有 12 种不同的方式来加载一个 int-32,具体取决于值)
于 2011-06-07T05:08:59.347 回答