Como puede ver en el siguiente código, he declarado un Action<>
objeto como una variable.
¿Alguien podría decirme por qué este delegado de método de acción se comporta como un método estático?
¿Por qué vuelve true
en el siguiente código?
Código:
public static void Main(string[] args)
{
Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };
Console.WriteLine(actionMethod.Method.IsStatic);
Console.Read();
}
Salida:
c#
.net
reflection
lambda
nunu
fuente
fuente
static
métodos.Ildasm
es realmente útil para comprender lo que realmente está sucediendo, tiendo a usar laIL
pestaña deLINQPad
para examinar pequeñas muestras.IL
pestañaLINQPad
e inferí C #. Algunas opciones para obtener el equivalente real de C # de la salida compilada sería usarILSpy
oReflector
en el ensamblado compilado, lo más probable es que necesite deshabilitar algunas opciones que intentarán mostrar las lambdas y no las clases generadas por el compilador.El "método de acción" es estático solo como un efecto secundario de la implementación. Este es un caso de un método anónimo sin variables capturadas. Como no hay variables capturadas, el método no tiene requisitos adicionales de vida útil más allá de los de las variables locales en general. Si hizo referencia a otras variables locales, su vida útil se extiende a la vida útil de esas otras variables (consulte la sección L.1.7, Variables locales , y la sección N.15.5.1, Variables externas capturadas , en la especificación C # 5.0).
Tenga en cuenta que la especificación C # solo habla de métodos anónimos que se convierten en "árboles de expresión", no en "clases anónimas". Si bien el árbol de expresión podría representarse como clases adicionales de C #, por ejemplo, en el compilador de Microsoft, esta implementación no es necesaria (como se reconoce en la sección M.5.3 en la especificación de C # 5.0). Por lo tanto, no está definido si la función anónima es estática o no. Además, la sección K.6 deja mucho abierto en cuanto a los detalles de los árboles de expresión.
fuente
El comportamiento de almacenamiento en caché de delegados cambió en Roslyn. Anteriormente, como se indicó, cualquier expresión lambda que no capturara variables se compilaba en un
static
método en el sitio de la llamada. Roslyn cambió este comportamiento. Ahora, cualquier lambda, que captura variables o no, se transforma en una clase de visualización:Dado este ejemplo:
Salida del compilador nativo:
Roslyn
Los cambios en el comportamiento de almacenamiento en caché de delegados en Roslyn hablan sobre por qué se realizó este cambio.
fuente
A partir de C # 6, esto siempre será predeterminado a los métodos de instancia ahora, y nunca será estático (por
actionMethod.Method.IsStatic
lo que siempre será falso).Ver aquí: ¿Por qué una lambda sin captura cambió de una estática en C # 5 a un método de instancia en C # 6?
y aquí: ¿ Diferencia en la evaluación de expresión estática lambda del compilador CSC y Roslyn?
fuente
El método no tiene cierres y también hace referencia a un método estático en sí mismo (Console.WriteLine), por lo que esperaría que fuera estático. El método declarará un tipo anónimo de cierre para un cierre, pero en este caso no es obligatorio.
fuente