c# - funciones - El compilador generó código incorrecto para métodos anónimos
linq lambda c# (2)
Se confirma como un error y ahora se corrigió: http://connect.microsoft.com/VisualStudio/feedback/details/766845/vs2012-the-compiler-generated-incorrect-codes-for-anonymous-methods
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.