我正在为动态类型实现构造函数,但是当我执行代码时,它会抛出一个异常,即 IL-Code 已损坏(FatalExecutionError
)。
IL代码
工作部分:
.method assembly specialname rtspecialname
instance void .ctor (
object '',
object '',
string ''
) cil managed
{
// Method begins at RVA 0xa370
// Code size 36 (0x24)
.maxstack 2
.locals init (
[0] class [mscorlib]System.Collections.IList,
[1] class [mscorlib]System.Collections.IList
)
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld object HIDDEN.PropertyComparison::_Object0
IL_0007: ldarg.0
IL_0008: ldarg.2
IL_0009: stfld object HIDDEN.PropertyComparison::_Object1
IL_000e: ldarg.0
IL_000f: ldarg.3
IL_0010: stfld string HIDDEN.PropertyComparison::_Name
// Return is here normally when not using the following code
添加以下 IL 代码时会发生错误。它必须与代码有关,或者是其他一些奇怪的行为,仅在此代码之前的代码中发生。
IL_0015: ldarg.1
IL_0016: isinst [mscorlib]System.Collections.IList
IL_001b: stloc.0
IL_001c: ldarg.2
IL_001d: isinst [mscorlib]System.Collections.IList
IL_0022: stloc.1
IL_0023: ret
} // end of method PropertyComparison::.ctor
关键是导致错误的行(似乎它们是错误的原因)只是一个简单的as
,当谈到 C# 时,仅此而已。如果有人有解决此问题的想法,那就太好了。
生成代码
PropertyComparisonType = _Module.DefineType("HIDDEN.PropertyComparison", TypeAttributes.Public, typeof(Object));
FieldBuilder object0Field = PropertyComparisonType.DefineField("_Object0", typeof(Object), FieldAttributes.Private);
FieldBuilder object1Field = PropertyComparisonType.DefineField("_Object1", typeof(Object), FieldAttributes.Private);
FieldBuilder equalField = PropertyComparisonType.DefineField("_Equal", typeof(Boolean), FieldAttributes.Private);
FieldBuilder nameField = PropertyComparisonType.DefineField("_Name", typeof(String), FieldAttributes.Private);
FieldBuilder childsField = PropertyComparisonType.DefineField("_Childs", typeof(IEnumerable<>).MakeGenericType(PropertyComparisonType), FieldAttributes.Private);
PropertyBuilder object0Property = PropertyComparisonType.DefineProperty("Object0", object0Field, setter: false);
PropertyBuilder object1Property = PropertyComparisonType.DefineProperty("Object1", object1Field, setter: false);
PropertyBuilder equalProperty = PropertyComparisonType.DefineProperty("Equal", equalField, setter: false);
PropertyBuilder nameProperty = PropertyComparisonType.DefineProperty("Name", nameField, setter: false);
PropertyBuilder childsProperty = PropertyComparisonType.DefineProperty("Childs", childsField, setter: false);
PropertyComparisonConstructor = PropertyComparisonType.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, new[] { typeof(Object), typeof(Object), typeof(String) });
ILGenerator il = PropertyComparisonConstructor.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, object0Field);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Stfld, object1Field);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_3);
il.Emit(OpCodes.Stfld, nameField);
LocalBuilder localList0 = il.DeclareLocal(typeof(IList));
LocalBuilder localList1 = il.DeclareLocal(typeof(IList));
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Isinst, typeof(IList));
il.Emit(OpCodes.Stloc, localList0);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Isinst, typeof(IList));
il.Emit(OpCodes.Stloc, localList1);
演员等级(编辑)
我注意到它OpCodes.Castclass
不会引发错误,但当运行时尝试强制转换无效对象时当然会引发运行时错误。
另一个疯狂的事情(编辑2)
我还注意到,当我用它交换最后一个Isinst
时Castclass
它可以正常工作而不会引发任何错误。这让我更加想知道这个错误。当注释掉生成 castclass 的行时,错误又回来了。