2016-03-27 11 views
8

Reflection.Emitを使用して多次元配列を作成し、その要素を設定します。配列の要素を設定するReflection.Emitを使用して多次元配列を作成する方法

newobj instance void int32[0..., 0...]::.ctor(int32, int32) 

そして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コード:

int[,] nums = new int[2, 2]; 
nums[1, 1] = 2; 

そしてILコードに変わり、次のC#コードと同様に :

call instance void int32[0..., 0...]::Set(int32, int32, int32) 

これら2つのIL文に対応するIL Generator.Emit()コードの種類は?

答えて

3

あなたは、ほとんど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); 

、あなたが実際にあなたがNewobjCallコードのために必要なConstructorInfoMethodInfoオブジェクトを取得するためにリフレクションを使用する必要があります。ここ

+1

ありがとう、最初に[] []を書いて間違ったILコードを手に入れました。 –

+0

'[、]'と '[] []'は2種類の配列を参照しています。違いについての詳細は、この質問(http://stackoverflow.com/questions/597720/what-are-the-differences-between-a-multidimensional-array-and-an-array-of-arrays)を参照してください。 – poke

3

は一例であり:

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]の値を充填し、その配列を返します。

関連する問題