metodos funciones expresiones delegados anonimos anonimas c# .net delegates cil anonymous-methods

c# - funciones - El compilador generó código incorrecto para métodos anónimos



Vea el siguiente código:

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(); arroja una excepción. Dentro del CIL generado del método Bang I got:

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 debería 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 Windows8 RTM, .NET framework 4.5

EDITAR Ahora este error está solucionado: http://connect.microsoft.com/VisualStudio/feedback/details/766845/vs2012-the-compiler-generated-incorrect-codes-for-anonymous-methods


Al principio: esta es una forma posible de solucionar esto, pero probablemente no sea una respuesta a su pregunta. (Pero los comentarios no tienen formato de código)

Creo que esto es similar a esto: Trampa de Variable Exterior , porque estás utilizando el método Foo () como una variable y hay un error (o tal vez una característica) en .NET

He intentado cambiar el método Bang () a 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.