2012-10-10 29 views
30

Véase el siguiente código:compilador genera código incorrecto para los métodos anónimos [MS error corregido]

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(); se produce una excepción. En el interior del CIL generada del método Bang llegué:

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

y la firma del método generado por el compilador:

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 
} 

creo que el código correcto debe ser '<>n__FabricatedMethod1'<class T>. ¿Es un error? Por cierto, sin usar delegate{ } (la expresión lambda es la misma), el código funciona bien con azúcares de sintaxis.

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

EDITAR estoy usando VS2012 RTMRel en RTM Windows8, .net framework 4.5

EDITAR Este error se ha corregido.

+1

Tu código funciona para mí. ¿Qué versión de C# /. Net/Visual Studio estás usando? ¿A qué plataforma estás apuntando? – jeroenh

+0

@jeroenh: C# 4.5 VS2012. –

+0

Lo intenté con VS2010, C# 4 y 3.5. No tengo acceso al 2012 en este momento, pero ciertamente lo intentaré esta noche. – jeroenh

Respuesta

3

Se confirma como un error y now fixed

Actualización: Conectar el artículo ya no existe. El error está arreglado.

+1

Lástima que nunca sabremos cuándo nos alcanzará. Microsoft realmente debería comunicarse mejor en ese sitio ... – leppie

1

Al principio: esta es una forma posible de solucionarlo, pero probablemente no sea una respuesta a su pregunta. (Sin embargo, los comentarios no disponemos de código de formateo)

Creo que esto es similar a esto: Outer Variable Trap, porque está utilizando el método foo() como una variable y hay un error (o tal vez una función) en .NET

he tratado de cambiar el método de explosión() para este

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

y funciona y el resultado es "base"

espero que ayude un poco.

+0

FYI, los comentarios * do * tienen formato de código, simplemente no puede incluir saltos de línea y todavía están limitados por el número total de caracteres (que incluye el descuento) –

Cuestiones relacionadas