[C#] كومبيلر ولدت رمز غير صحيح للطرق المجهولة


Answers

في البداية - هذه هي الطريقة الممكنة لإصلاح هذا، ولكن ربما ليس إجابة لسؤالك. (ولكن التعليقات لا تملك رمز تشكيل)

وأعتقد أن هذا يشبه هذا: فخ المتغير الخارجي ، لأنك تستخدم فو () طريقة كمتغير وهناك خطأ (أو ربما ميزة) في .NET

لقد حاولت تغيير طريقة بانغ () إلى هذا

public void Bang()
{
    Action baseMethod = base.Foo<string>;
    Action bang = new Action(delegate { baseMethod(); });
    bang();    //VerificationException is thrown
}

ويعمل والنتيجة هي "قاعدة"

آمل أن يساعد قليلا.

Question

راجع التعليمات البرمجية التالية:

public abstract class Base
{
    public virtual void Foo<T>() where T : class
    {
        Console.WriteLine("base");
    }
}

public class Derived : Base
{
    public override void Foo<T>()
    {
        Console.WriteLine("derived");
    }

    public void Bang()
    {
        Action bang = new Action(delegate { base.Foo<string>(); });
        bang();    //VerificationException is thrown
    }
}

new Derived().Bang(); يلقي استثناء. داخل سيل ولدت من طريقة Bang حصلت:

call instance void ConsoleApp.Derived::'<>n__FabricatedMethod1'<string>()

وتوقيع طريقة تجميع البيانات:

method private hidebysig 
    instance void '<>n__FabricatedMethod1'<T> () cil managed 
{
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
        01 00 00 00
    )       
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void ConsoleApp.Base::Foo<!!T>()
    IL_0006: ret
}

أعتقد أن الرمز الصحيح يجب أن يكون '<>n__FabricatedMethod1'<class T> . هل هذه حقيب؟ بالمناسبة، دون استخدام delegate{ } (تعبير لامدا هو نفسه)، التعليمات البرمجية يعمل بشكل جيد مع السكريات بناء الجملة.

Action good = new Action(base.Foo<string>());
good();  //fine

إديت أنا باستخدام VS2012 رتمريل في windows8 رتم، .net الإطار 4.5

إديت تم إصلاح هذا الخطأ الآن: http://connect.microsoft.com/VisualStudio/feedback/details/766845/vs2012-the-compiler-generated-incorrect-codes-for-anonymous-methods