لماذا تسبب استدعاء DynamicMethod بمثيل من صفي الخاص استثناء؟

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

سؤال

أنا أتعلم CIL من خلال جعل وظائفي الخاصة في وقت التشغيل مع Reflection.Emit. وبعد أنا فعلا من فاجأ كيف كانت الأمور السهلة حتى الآن لكنني أصبت بشيء لا أستطيع تخمين طريقي ولا يمكنني العثور على أي شيء قريب في المستندات.

أحاول إنشاء وظيفة تقوم ببساطة بطباعة فئة بسيطة للغاية حددتها. إذا قمت بتغيير التعليمات البرمجية الخاصة بي stringS، أقول، إنه يعمل ولكنه دائما يفشل في الركض عندما اجري مثيل من صفي A.

ما هو غريب، يمكنني التعليق على جسدي وظيفتي ولا يزال يفشل مع TargetInvocationException. وبعد يجب أن يكون بسيطا جدا لكنني لا أستطيع أن أرى ما الأمر!

class A
{
    public override string  ToString()
    {
        return "AAA!";
    }
}

class Program
{
    static void Main(string[] args)
    {
        DynamicMethod func = new DynamicMethod("func", null, new Type[] { typeof(A) });

        ILGenerator il = func.GetILGenerator();

        //il.Emit(OpCodes.Ldarg_0);
        //il.Emit(OpCodes.Box, typeof(A));
        //il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(A) }));

        il.Emit(OpCodes.Ret);

        func.Invoke(null, new object[] { new A() });

        Console.Read();
    }
}

ما الذي أفعله خطأ في جعل هذا يرفع استثناء؟ لماذا يحدث هذا فقط مع فصولي؟

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

المحلول

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

نصائح أخرى

كان سخيا جدا في الواقع. قضيت عدة ساعات في ذلك، لكن عندما تابعت نصيحة لوران etiemble وقمت بإنشاء مفوض استثناء أخبرني أن صفي لم يكن علنيا.

المحلول: أضف الكلمة الأساسية العامة من قبل class A. وبعد يعمل تماما. أنا عرف كان عليه أن يكون شيئا بسيطا بجنون.

أولا - يجب أن لا تنبعث منها Box OpCode منذ ذلك الحين A هو فئة ولا تحتاج إلى أن تكون محاصر. الملاكمة هي فقط لأنواع القيمة.

ثانيا - السبب في عدم وجود فشل هو أن الطريقة لا تحتوي على إذن بالوصول إلى الفئة A (ليست عامة). إما اتخاذ A public أو يمكنك توجيه برامج التحويل البرمجي JIT إلى تخطي الشيكات الرؤية باستخدام هذا المنشئ والتمرير true إلى معلمة SKIPVIEMITITION.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top