質問

動的型のコンストラクターを実装していますが、コードを実行しているときは、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
.

ポイントは、エラーを引き起こす行(エラーの理由であるようです)は、C#と話すときに単純なasです。誰かがこの問題を解決するというアイデアを持っているならば素晴らしいでしょう。

コードを生成する
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)

も、最後のIsinstCastclassに交換すると、エラーを投げずに機能するように機能します。これはこのエラーについてさらに疑問に思うようになります。 CASTCLASSを生成する行を再度コメントアウトしたとき。

役に立ちましたか?

解決

I tried your code (had to change the constructor to MethodAttributes.Public to get it to work) and it worked flawlessly. I apologize that this isn't really an answer, but wanted to show the code that I used in case it points to any differences that might be helpful:

class Program
{
    static void Main(string[] args)
    {
        var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("foo"), AssemblyBuilderAccess.RunAndSave);
        var _Module = assembly.DefineDynamicModule("fooModule");

        var 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);

        var PropertyComparisonConstructor = PropertyComparisonType.DefineConstructor(MethodAttributes.Public, 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);
        il.Emit(OpCodes.Ret);

        var type = PropertyComparisonType.CreateType();

        var list1 = new List<string>();
        var list2 = new List<string>();
        var s = "prop";
        var instance = Activator.CreateInstance(type, list1, list2, s);
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top