[英]How to create multi-dimensional array using Reflection.Emit
I want to create a multi-dimensional array using Reflection.Emit and set it's element. 我想使用Reflection.Emit创建一个多维数组并设置它的元素。 Like the following C# code:
像下面的C#代码一样:
int[,] nums = new int[2, 2];
nums[1, 1] = 2;
And turn into IL code: 转入IL代码:
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: ldc.i4.2
IL_0003: newobj instance void int32[0..., 0...]::.ctor(int32, int32)
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.1
IL_000b: ldc.i4.1
IL_000c: ldc.i4.2
IL_000d: call instance void int32[0..., 0...]::Set(int32, int32, int32)
The IL code to create array: 用于创建数组的IL代码:
newobj instance void int32[0..., 0...]::.ctor(int32, int32)
And the IL code to set the array's element: 以及用于设置数组元素的IL代码:
call instance void int32[0..., 0...]::Set(int32, int32, int32)
What kind of IL Generator.Emit() code corresponding to those two IL sentence? 什么样的IL Generator.Emit()代码对应那两个IL句子?
You can almost translate that IL verbally: 你几乎可以口头翻译那个IL:
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Ldc_I4_2);
var constructor = typeof(int[,]).GetConstructor(new Type[]{ typeof(int), typeof(int) });
il.Emit(OpCodes.Newobj, constructor);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ldc_I4_2);
var setMethod = typeof(int[,]).GetMethod("Set");
il.Emit(OpCodes.Call, setMethod);
Of course, you need to use reflection to actually get the ConstructorInfo
and the MethodInfo
object you need for the Newobj
and Call
codes. 当然,您需要使用反射来实际获取
Newobj
和Call
代码所需的ConstructorInfo
和MethodInfo
对象。
Here is an example: 这是一个例子:
DynamicMethod method =
new DynamicMethod("Test" , typeof(int[,]), new Type[]{});
var generator = method.GetILGenerator();
//get the constructor that takes in 2 integers (the dimensions of the array)
var constructor = typeof (int[,])
.GetConstructor(new {typeof (int), typeof (int)});
//get the Set method that takes in 3 integers; 2 indexes and the value
var set_method = typeof(int[,])
.GetMethod("Set", new[] { typeof(int), typeof(int), typeof(int) });
var local = generator.DeclareLocal(typeof (int[,])); //local variable to reference the array
generator.Emit(OpCodes.Ldc_I4_2);
generator.Emit(OpCodes.Ldc_I4_2);
generator.Emit(OpCodes.Newobj, constructor); //invoke the constructor to create the array
generator.Emit(OpCodes.Stloc, local);
generator.Emit(OpCodes.Ldloc, local);
generator.Emit(OpCodes.Ldc_I4_1);
generator.Emit(OpCodes.Ldc_I4_1);
generator.Emit(OpCodes.Ldc_I4_2);
generator.Emit(OpCodes.Call, set_method); //call the Set method to set the value
generator.Emit(OpCodes.Ldloc, local);
generator.Emit(OpCodes.Ret);
var result_method = (Func<int[,]>)method.CreateDelegate(typeof (Func<int[,]>));
var result = result_method(); //returns the array
This example creates a dynamic method that creates the array, fills the value in [1,1], and then returns that array. 此示例创建一个动态方法,用于创建数组,填充[1,1]中的值,然后返回该数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.