[英]How to create multi-dimensional array using Reflection.Emit
我想使用Reflection.Emit創建一個多維數組並設置它的元素。 像下面的C#代碼一樣:
int[,] nums = new int[2, 2];
nums[1, 1] = 2;
轉入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)
用於創建數組的IL代碼:
newobj instance void int32[0..., 0...]::.ctor(int32, int32)
以及用於設置數組元素的IL代碼:
call instance void int32[0..., 0...]::Set(int32, int32, int32)
什么樣的IL Generator.Emit()代碼對應那兩個IL句子?
你幾乎可以口頭翻譯那個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);
當然,您需要使用反射來實際獲取Newobj
和Call
代碼所需的ConstructorInfo
和MethodInfo
對象。
這是一個例子:
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
此示例創建一個動態方法,用於創建數組,填充[1,1]中的值,然后返回該數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.