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

我的 C# 代码是

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

使用 ildasm ,我意识到为上面生成了以下 IL 代码
C# 代码。
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 代码?

最佳答案

啊,好 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,具体取决于值)
  • 关于c# - 为二维数组生成 IL,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6260750/

    10-12 16:21