استثناء عند محاولة تنفيذ التعليمات البرمجية التي تم إنشاؤها

StackOverflow https://stackoverflow.com/questions/9519091

  •  14-11-2019
  •  | 
  •  

سؤال

أقوم بتنفيذ مُنشئ لنوع ديناميكي ولكن عندما أقوم بتنفيذ التعليمات البرمجية فإنه يطرح لي استثناءً وهو أن رمز IL تالف ( FatalExecutionError ).

رمز إيل

جزء العمل:

.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 يعمل دون رمي أي خطأ.وهذا يجعلني أتساءل أكثر عن هذا الخطأ.عند التعليق على الأسطر التي تولد فئة cast، يعود الخطأ مرة أخرى.

هل كانت مفيدة؟

المحلول

لقد جربت الكود الخاص بك (اضطررت إلى تغيير المنشئ إلى MethodAttributes.Public للحصول عليه للعمل) وعملت لا تشوبه شائبة.أعتذر لأن هذه ليست إجابة حقًا، ولكني أردت إظهار الكود الذي استخدمته في حالة الإشارة إلى أي اختلافات قد تكون مفيدة:

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