2012-10-10 6 views
30

Siehe den folgenden Code:Compiler generiert falschen Code für anonyme Methoden [MS BUG FIXED]

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(); eine Ausnahme auslöst. Im Inneren des erzeugten CIL des Verfahrens Bang Ich habe:

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

und die Unterschrift des Compiler erzeugt Methode:

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 
} 

denke ich, der richtige Code '<>n__FabricatedMethod1'<class T> sein sollte. Ist es ein Fehler? Übrigens, ohne (Lambda-Ausdruck ist der gleiche), der Code funktioniert gut mit Syntax Zucker.

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

EDIT ich VS2012 RTMRel in windows8 RTM bin mit .NET Framework 4.5

EDIT Dieser Fehler ist nun behoben.

+1

Ihr Code funktioniert für mich. Welche Version von C# /. Net/Visual Studio verwenden Sie? Auf welche Plattform zielen Sie? – jeroenh

+0

@jeroenh: C# 4.5 VS2012. –

+0

Ich versuchte mit VS2010, C# 4 und 3.5. Habe gerade keinen Zugang zu 2012, werde es aber heute Abend versuchen. – jeroenh

Antwort

3

Es wird als Fehler bestätigt und now fixed

Update: der Artikel Connect nicht mehr existiert. Der Fehler ist behoben.

+1

Schade, wir werden nie wissen, wann uns das erreichen wird. Microsoft sollte wirklich besser auf dieser Seite kommunizieren ... – leppie

1

Zuerst - Dies ist ein möglicher Weg, wie das zu beheben, aber wahrscheinlich keine Antwort auf Ihre Frage. (Aber Kommentare haben keine Code Formatierung)

Ich glaube, das ist ähnlich zu diesem: Outer Variable Trap, weil Sie Foo() -Methode als Variable verwenden und es gibt einen Fehler (oder vielleicht ein Feature) in .NET

Bang() -Methode zu dieser

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

und es funktioniert und das Ergebnis ist „Basis“

ich hoffe, es hilft ein wenig zu ändern

ich habe versucht.

+0

FYI, Kommentare * haben * Code-Formatierung, Sie können nicht nur Zeilenumbrüche enthalten und sind immer noch durch die Gesamtzahl der Zeichen begrenzt (einschließlich Abschlag) –