Leí rápidamente la documentación de Microsoft Lambda Expression .
Sin embargo, este tipo de ejemplo me ha ayudado a comprender mejor:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
Aún así, no entiendo por qué es una innovación. Es solo un método que muere cuando termina la "variable del método", ¿verdad? ¿Por qué debería usar esto en lugar de un método real?
delegate
hay en C #, les recomiendo leer esto antes de leer el resto de esta página: stackoverflow.com/questions/2082615/…Respuestas:
Las expresiones lambda son una sintaxis más simple para delegados anónimos y se pueden usar en todas partes donde se puede usar un delegado anónimo. Sin embargo, lo contrario no es cierto; Las expresiones lambda se pueden convertir en árboles de expresión, lo que permite mucha magia como LINQ to SQL.
El siguiente es un ejemplo de una expresión LINQ to Objects que utiliza delegados anónimos y luego expresiones lambda para mostrar qué tan fáciles de ver son:
Las expresiones Lambda y los delegados anónimos tienen una ventaja sobre escribir una función separada: implementan cierres que pueden permitirle pasar el estado local a la función sin agregar parámetros a la función o crear objetos de un solo uso.
Los árboles de expresión son una nueva característica muy poderosa de C # 3.0 que permite que una API mire la estructura de una expresión en lugar de simplemente obtener una referencia a un método que se puede ejecutar. Una API solo tiene que convertir un parámetro delegado en un
Expression<T>
parámetro y el compilador generará un árbol de expresión a partir de una lambda en lugar de un delegado anónimo:llamado como:
se convierte en:
A este último se le pasará una representación del árbol de sintaxis abstracta que describe la expresión
x > 5
. LINQ to SQL se basa en este comportamiento para poder convertir expresiones C # en las expresiones SQL deseadas para el filtrado / pedido / etc. en el lado del servidor.fuente
Las funciones y expresiones anónimas son útiles para métodos únicos que no se benefician del trabajo adicional requerido para crear un método completo.
Considere este ejemplo:
versus
Estos son funcionalmente equivalentes.
fuente
Los encontré útiles en una situación en la que quería declarar un controlador para algún evento de control, usando otro control. Para hacerlo normalmente, tendría que almacenar las referencias de los controles en los campos de la clase para poder usarlos en un método diferente al que se crearon.
gracias a las expresiones lambda puedes usarlo así:
Más fácil.
fuente
Lambda ha limpiado la sintaxis de delegado anónimo de C # 2.0 ... por ejemplo
Se hizo en C # 2.0 de esta manera:
Funcionalmente, hacen exactamente lo mismo, es una sintaxis mucho más concisa.
fuente
Esta es solo una forma de usar una expresión lambda. Puede usar una expresión lambda en cualquier lugar donde pueda usar un delegado. Esto le permite hacer cosas como esta:
Este código buscará en la lista una entrada que coincida con la palabra "hola". La otra forma de hacerlo es pasar un delegado al método Find, como este:
EDITAR :
En C # 2.0, esto podría hacerse utilizando la sintaxis de delegado anónimo:
Lambda ha limpiado significativamente esa sintaxis.
fuente
string
ay devuelve abool
) como un parámetro para elFind
método mismo.Microsoft nos ha dado una forma más limpia y conveniente de crear delegados anónimos llamados expresiones Lambda. Sin embargo, no se presta mucha atención a la parte de expresiones de esta declaración. Microsoft lanzó un espacio de nombres completo, System.Linq.Expressions , que contiene clases para crear árboles de expresión basados en expresiones lambda. Los árboles de expresión están formados por objetos que representan la lógica. Por ejemplo, x = y + z es una expresión que podría ser parte de un árbol de expresión en .Net. Considere el siguiente ejemplo sencillo:
Este ejemplo es trivial. Y estoy seguro de que está pensando: "Esto es inútil ya que podría haber creado directamente el delegado en lugar de crear una expresión y compilarla en tiempo de ejecución". Y tú estarías bien. Pero esto proporciona la base para los árboles de expresión. Hay una serie de expresiones disponibles en los espacios de nombres de Expresiones, y usted puede construir el suyo propio. Creo que puede ver que esto podría ser útil cuando no sabe exactamente cuál debería ser el algoritmo en el momento del diseño o la compilación. Vi un ejemplo en alguna parte para usar esto para escribir una calculadora científica. También podría usarlo para sistemas bayesianos o para programación genética(AI). Algunas veces en mi carrera tuve que escribir una funcionalidad similar a Excel que permitía a los usuarios ingresar expresiones simples (suma, resta, etc.) para operar con los datos disponibles. En pre.Net 3.5, tuve que recurrir a un lenguaje de script externo a C #, o tuve que usar la funcionalidad de emisión de código en reflexión para crear código .Net sobre la marcha. Ahora usaría árboles de expresión.
fuente
Ahorra la necesidad de tener métodos que solo se usan una vez en un lugar específico de ser definidos lejos del lugar donde se usan. Los buenos usos son como comparadores de algoritmos genéricos como la ordenación, donde luego puede definir una función de ordenación personalizada en la que invoca la ordenación en lugar de forzarlo a buscar en otro lado para ver qué está ordenando.
Y no es realmente una innovación. LISP ha tenido funciones lambda durante aproximadamente 30 años o más.
fuente
También puede encontrar el uso de expresiones lambda al escribir códigos genéricos para actuar sobre sus métodos.
Por ejemplo: función genérica para calcular el tiempo que tarda una llamada al método. (es decir,
Action
aquí)Y puede llamar al método anterior usando la expresión lambda de la siguiente manera,
Expression le permite obtener valor de retorno de su método y también param
fuente
La expresión lambda es una forma concisa de representar un método anónimo. Tanto los métodos anónimos como las expresiones Lambda le permiten definir la implementación del método en línea, sin embargo, un método anónimo requiere explícitamente que defina los tipos de parámetros y el tipo de retorno para un método. La expresión Lambda utiliza la función de inferencia de tipo de C # 3.0 que permite al compilador inferir el tipo de la variable en función del contexto. ¡Es muy conveniente porque eso nos ahorra mucho tipeo!
fuente
Una expresión lambda es como un método anónimo escrito en lugar de una instancia de delegado.
Considere la expresión lambda
x => x * x;
El código de una expresión lambda puede ser un bloque de instrucción en lugar de una expresión.
Ejemplo
Nota:
Func
es un delegado genérico predefinido.Referencias
fuente
Muchas veces, solo está utilizando la funcionalidad en un solo lugar, por lo que hacer un método simplemente abarrota la clase.
fuente
Es una forma de realizar pequeñas operaciones y ponerlas muy cerca de donde se usan (no muy diferente de declarar una variable cerca de su punto de uso). Se supone que esto hará que su código sea más legible. Al anonimizar la expresión, también está haciendo que sea mucho más difícil para alguien descifrar su código de cliente si la función se usa en otro lugar y se modifica para "mejorarla".
Del mismo modo, ¿por qué necesitas usar foreach? Puede hacer todo en foreach con un bucle simple o simplemente usando IEnumerable directamente. Respuesta: no lo necesita , pero hace que su código sea más legible.
fuente
La innovación está en el tipo seguridad y transparencia. Aunque no declara tipos de expresiones lambda, se infieren y pueden usarse mediante búsqueda de código, análisis estático, herramientas de refactorización y reflexión de tiempo de ejecución.
Por ejemplo, antes de que pudieras haber usado SQL y pudieras recibir un ataque de inyección SQL, porque un hacker pasó una cadena donde normalmente se esperaba un número. Ahora usaría una expresión lambda de LINQ, que está protegida contra eso.
No es posible construir una API LINQ en delegados puros, porque requiere combinar árboles de expresión antes de evaluarlos.
En 2016, la mayoría de los lenguajes populares tienen soporte de expresión lambda , y C # fue uno de los pioneros en esta evolución entre los lenguajes imperativos convencionales.
fuente
Esta es quizás la mejor explicación sobre por qué usar expresiones lambda -> https://youtu.be/j9nj5dTo54Q
En resumen, es para mejorar la legibilidad del código, reducir las posibilidades de errores al reutilizar en lugar de replicar el código, y aprovechar la optimización que ocurre detrás de escena.
fuente
El mayor beneficio de las expresiones lambda y las funciones anónimas es el hecho de que permiten que el cliente (programador) de una biblioteca / marco inyecte funcionalidad mediante código en la biblioteca / marco dada (como es LINQ, ASP.NET Core y muchos otros) de una manera que los métodos regulares no pueden. Sin embargo, su fortaleza no es obvia para un programador de aplicaciones único, sino para el que crea bibliotecas que luego serán utilizadas por otros que deseen configurar el comportamiento del código de la biblioteca o el que usa bibliotecas. Entonces, el contexto de usar efectivamente una expresión lambda es el uso / creación de una biblioteca / marco.
Además, dado que describen el código de uso único, no tienen que ser miembros de una clase en la que eso conducirá a una mayor complejidad del código. Imagine tener que declarar una clase con un enfoque poco claro cada vez que queramos configurar la operación de un objeto de clase.
fuente