如何将此 IL 代码转换为 C# 中的 Reflection.Emit?
这是我试图将其转换为 C# 的 IL 代码,但没有成功:
.assembly _
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (
01 00 08 00 00 00 00 00
)
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (
01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78
63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01
)
.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (
01 00 02 00 00 00 00 00
)
.hash algorithm 0x00008004 // SHA1
.ver 0:0:0:0
}
.class private auto ansi '<Module>'
{
} // end of class <Module>
.class public auto ansi MYCLASS
extends [mscorlib]System.Object
{
// Fields
.field private object _myTextBlock
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Methods
.method public specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2050
// Code size 23 (0x17)
.maxstack 8
// sequence point: hidden
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: newobj instance void [mscorlib]System.Object::.ctor()
IL_000c: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
IL_0011: call instance void MYCLASS::set_myTextBlock(object)
IL_0016: ret
} // end of method MYCLASS::.ctor
.method public specialname
instance object get_myTextBlock () cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2068
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld object MYCLASS::_myTextBlock
IL_0006: ret
} // end of method MYCLASS::get_myTextBlock
.method public specialname
instance void set_myTextBlock (
object AutoPropertyValue
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2070
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
IL_0007: stfld object MYCLASS::_myTextBlock
IL_000c: ret
} // end of method MYCLASS::set_myTextBlock
// Properties
.property instance object myTextBlock()
{
.get instance object MYCLASS::get_myTextBlock()
.set instance void MYCLASS::set_myTextBlock(object)
}
} // end of class MYCLASS
这就是我要翻译的代码:
public class MYCLASS : object
{
public object myTextBlock { get; set; } = new object();
}
这是我到目前为止正在运行的代码,但没有继承该类或初始化属性:
public Type CreateClass(string className, Dictionary<string, Type> properties)
{
AssemblyName myAsmName = new AssemblyName("RoadAssembly");
AssemblyBuilder myAssembly = myAssembly.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder myModule = myAssembly.DefineDynamicModule("RoadAssembly");
TypeBuilder myType = myModule.DefineType(className, TypeAttributes.Public);
myType.DefineDefaultConstructor(MethodAttributes.Public);
foreach (var o in properties)
{
PropertyBuilder prop = myType.DefineProperty(o.Key, PropertyAttributes.HasDefault, o.Value, null/* TODO Change to default(_) if this is not a reference type */);
FieldBuilder field = myType.DefineField("_" + o.Key, o.Value, FieldAttributes.Private);
MethodBuilder getter = myType.DefineMethod("get_" + o.Key, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, o.Value, Type.EmptyTypes);
ILGenerator getterIL = getter.GetILGenerator();
getterIL.Emit(OpCodes.Ldarg_0);
getterIL.Emit(OpCodes.Ldfld, field);
getterIL.Emit(OpCodes.Ret);
MethodBuilder setter = myType.DefineMethod("set_" + o.Key, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null/* TODO Change to default(_) if this is not a reference type */, new Type[] { o.Value });
ILGenerator setterIL = setter.GetILGenerator();
setterIL.Emit(OpCodes.Ldarg_0);
setterIL.Emit(OpCodes.Ldarg_1);
setterIL.Emit(OpCodes.Stfld, field);
setterIL.Emit(OpCodes.Ret);
prop.SetGetMethod(getter);
prop.SetSetMethod(setter);
}
return myType.CreateType();
}
我已经尝试过用于转换“新对象”部分但没有成功的类型的构造函数,这是我尝试的构造函数:
{
ConstructorBuilder cBuilder = myType.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { o.Value });
ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0] { });
ILGenerator cil = cBuilder.GetILGenerator();
cil.Emit(OpCodes.Ldarg_0);
cil.Emit(OpCodes.Newobj, conObj);
cil.Emit(OpCodes.Stfld, field);
cil.Emit(OpCodes.Ldarg_0);
cil.Emit(OpCodes.Call, conObj);
cil.Emit(OpCodes.Ret);
}
我不明白 OpCode 是如何工作的,也不明白我必须将此构造函数放在函数中的位置,以便我可以正确初始化当我创建一个对象时这个类这堂课。
This is the IL code I'm trying to translate to C# without succes:
.assembly _
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (
01 00 08 00 00 00 00 00
)
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (
01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78
63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01
)
.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (
01 00 02 00 00 00 00 00
)
.hash algorithm 0x00008004 // SHA1
.ver 0:0:0:0
}
.class private auto ansi '<Module>'
{
} // end of class <Module>
.class public auto ansi MYCLASS
extends [mscorlib]System.Object
{
// Fields
.field private object _myTextBlock
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Methods
.method public specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2050
// Code size 23 (0x17)
.maxstack 8
// sequence point: hidden
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: newobj instance void [mscorlib]System.Object::.ctor()
IL_000c: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
IL_0011: call instance void MYCLASS::set_myTextBlock(object)
IL_0016: ret
} // end of method MYCLASS::.ctor
.method public specialname
instance object get_myTextBlock () cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2068
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld object MYCLASS::_myTextBlock
IL_0006: ret
} // end of method MYCLASS::get_myTextBlock
.method public specialname
instance void set_myTextBlock (
object AutoPropertyValue
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2070
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
IL_0007: stfld object MYCLASS::_myTextBlock
IL_000c: ret
} // end of method MYCLASS::set_myTextBlock
// Properties
.property instance object myTextBlock()
{
.get instance object MYCLASS::get_myTextBlock()
.set instance void MYCLASS::set_myTextBlock(object)
}
} // end of class MYCLASS
This is what I'm translating from:
public class MYCLASS : object
{
public object myTextBlock { get; set; } = new object();
}
This is what I have so far that is working but is not inheriting the class or initialising the properties:
public Type CreateClass(string className, Dictionary<string, Type> properties)
{
AssemblyName myAsmName = new AssemblyName("RoadAssembly");
AssemblyBuilder myAssembly = myAssembly.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder myModule = myAssembly.DefineDynamicModule("RoadAssembly");
TypeBuilder myType = myModule.DefineType(className, TypeAttributes.Public);
myType.DefineDefaultConstructor(MethodAttributes.Public);
foreach (var o in properties)
{
PropertyBuilder prop = myType.DefineProperty(o.Key, PropertyAttributes.HasDefault, o.Value, null/* TODO Change to default(_) if this is not a reference type */);
FieldBuilder field = myType.DefineField("_" + o.Key, o.Value, FieldAttributes.Private);
MethodBuilder getter = myType.DefineMethod("get_" + o.Key, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, o.Value, Type.EmptyTypes);
ILGenerator getterIL = getter.GetILGenerator();
getterIL.Emit(OpCodes.Ldarg_0);
getterIL.Emit(OpCodes.Ldfld, field);
getterIL.Emit(OpCodes.Ret);
MethodBuilder setter = myType.DefineMethod("set_" + o.Key, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null/* TODO Change to default(_) if this is not a reference type */, new Type[] { o.Value });
ILGenerator setterIL = setter.GetILGenerator();
setterIL.Emit(OpCodes.Ldarg_0);
setterIL.Emit(OpCodes.Ldarg_1);
setterIL.Emit(OpCodes.Stfld, field);
setterIL.Emit(OpCodes.Ret);
prop.SetGetMethod(getter);
prop.SetSetMethod(setter);
}
return myType.CreateType();
}
I have tried making a constructor for the type to translate the "New Object" part with no success, this is my attempted constructor:
{
ConstructorBuilder cBuilder = myType.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { o.Value });
ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0] { });
ILGenerator cil = cBuilder.GetILGenerator();
cil.Emit(OpCodes.Ldarg_0);
cil.Emit(OpCodes.Newobj, conObj);
cil.Emit(OpCodes.Stfld, field);
cil.Emit(OpCodes.Ldarg_0);
cil.Emit(OpCodes.Call, conObj);
cil.Emit(OpCodes.Ret);
}
I do not understand how the OpCodes work or where I have to place this constructor in my function so I can properly initialise the objects of this class when I create an object of this class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论