動的型のコンストラクターを実装していますが、コードを実行すると、ILコードが破損しているという例外がスローされます(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);
Castclass(編集)
OpCodes.Castclassエラーはスローされませんが、ランタイムが無効なオブジェクトをキャストしようとすると、もちろんランタイムエラーがスローされることに気付きました。
もう一つのクレイジーなこと(編集2)
Isinst最後のものを交換するとCastclass、エラーをスローせずに動作することにも気づきました。これにより、このエラーについてさらに疑問に思うようになります。キャストクラスを生成する行をコメントアウトすると、エラーが再び発生します。