Ben IL koduna bu basit sınıfını dönüştürmek çalışıyorum: Basit sınıfı IL'ye dönüştürmek bazı geçersiz IL kodları nedeniyle başarısız oldu mu?
public class IL {
Dictionary<string, int> props = new Dictionary<string, int>() { {"1",1} };
}
Aslında ben dinamik olarak sınıf oluşturmak için
Emit
kullanmayı denemeden önce IL talimatlarını bilmek
ILDasm
kullandı. gösterir sonucudur: Bu itibaren
.class public auto ansi beforefieldinit IL
extends [mscorlib]System.Object
{
.field private class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> props
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
//
.maxstack 4
.locals init (class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> V_0)
IL_0000: ldarg.0
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr "1"
IL_000d: ldc.i4.1
IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0,
!1)
IL_0013: ldloc.0
IL_0014: stfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> IL::props
IL_0019: ldarg.0
IL_001a: call instance void [mscorlib]System.Object::.ctor()
IL_001f: ret
} // end of method IL::.ctor
} // end of class IL
, böyle Emit
kullanarak çalıştı: kullanmaktan Şimdi
var aBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new System.Reflection.AssemblyName("test"), AssemblyBuilderAccess.Run);
var mBuilder = aBuilder.DefineDynamicModule("module");
var tBuilder = mBuilder.DefineType("IL");
var field = tBuilder.DefineField("props", typeof(Dictionary<string, int>), System.Reflection.FieldAttributes.Private);
var con = tBuilder.DefineConstructor(System.Reflection.MethodAttributes.Public |
System.Reflection.MethodAttributes.HideBySig |
System.Reflection.MethodAttributes.SpecialName |
System.Reflection.MethodAttributes.RTSpecialName,
System.Reflection.CallingConventions.HasThis, Type.EmptyTypes);
var conIL = con.GetILGenerator();
conIL.Emit(OpCodes.Ldarg_0);
conIL.Emit(OpCodes.Newobj, typeof(Dictionary<string,int>).GetConstructor(Type.EmptyTypes));
conIL.Emit(OpCodes.Stloc_0);
conIL.Emit(OpCodes.Ldloc_0);
conIL.Emit(OpCodes.Ldstr, "1");
conIL.Emit(OpCodes.Ldc_I4_1);
conIL.Emit(OpCodes.Callvirt, typeof(Dictionary<string, int>).GetMethod("Add"));
conIL.Emit(OpCodes.Ldloc_0);
conIL.Emit(OpCodes.Stfld, field);
conIL.Emit(OpCodes.Ldarg_0);
conIL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
conIL.Emit(OpCodes.Ret);
deneyin: IL kodu yanlış olur demektir
var t = tBuilder.CreateType();
var instance = Activator.CreateInstance(t);//exception has been thrown here
//saying "Common Language Runtime detected an invalid program."
bir noktada. Ama aslında ILDasm
tarafından üretilen ile karşılaştırıldığında, ben hiçbir fark görmüyorum. Burada sorun nedir?
Teşekkür ederim, eğer daha iyi anlamış olsaydım tamam olurdu. – Hopeless