C# Language
Expresiones lambda
Buscar..
Observaciones
Una expresión lambda es una sintaxis para crear funciones anónimas en línea. Más formalmente, de la Guía de programación de C # :
Una expresión lambda es una función anónima que puede usar para crear delegados o tipos de árbol de expresiones. Al utilizar expresiones lambda, puede escribir funciones locales que pueden pasarse como argumentos o devolverse como el valor de las llamadas a funciones.
Una expresión lambda se crea utilizando el operador =>
. Ponga los parámetros en el lado izquierdo del operador. En el lado derecho, ponga una expresión que pueda usar esos parámetros; esta expresión se resolverá como el valor de retorno de la función. Más raramente, si es necesario, se puede usar un {code block}
completo en el lado derecho. Si el tipo de retorno no es nulo, el bloque contendrá una declaración de retorno.
Pasar una expresión Lambda como un parámetro a un método
List<int> l2 = l1.FindAll(x => x > 6);
Aquí x => x > 6
es una expresión lambda que actúa como un predicado que se asegura de que solo se devuelvan los elementos por encima de 6.
Expresiones de Lambda como taquigrafía para la inicialización de delegados
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;
La sintaxis de la expresión Lambda anterior es equivalente al siguiente código detallado:
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = delegate(int x){
return x * 2;
};
Lambdas tanto para `Func` como para` Action`
Normalmente, las lambdas se usan para definir funciones simples (generalmente en el contexto de una expresión linq):
var incremented = myEnumerable.Select(x => x + 1);
Aquí el return
es implícito.
Sin embargo, también es posible pasar acciones como lambdas:
myObservable.Do(x => Console.WriteLine(x));
Expresiones de Lambda con múltiples parámetros o sin parámetros
Use paréntesis alrededor de la expresión a la izquierda del operador =>
para indicar múltiples parámetros.
delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;
De manera similar, un conjunto vacío de paréntesis indica que la función no acepta parámetros.
delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";
Poner múltiples declaraciones en una declaración Lambda
A diferencia de una expresión lambda, una declaración lambda puede contener varias declaraciones separadas por punto y coma.
delegate void ModifyInt(int input);
ModifyInt addOneAndTellMe = x =>
{
int result = x + 1;
Console.WriteLine(result);
};
Tenga en cuenta que las declaraciones están entre llaves {}
.
Recuerde que la declaración lambdas no se puede utilizar para crear árboles de expresión.
Lambdas se puede emitir como `Func` y` Expresión`
Suponiendo la siguiente clase de Person
:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
La siguiente lambda:
p => p.Age > 18
Se puede pasar como argumento a ambos métodos:
public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)
Porque el compilador es capaz de transformar lambdas tanto a delegados como a Expression
s.
Obviamente, los proveedores de LINQ dependen en gran medida de Expression
s (expuesto principalmente a través de la interfaz IQueryable<T>
) para poder analizar las consultas y traducirlas a las consultas almacenadas.
Expresión Lambda como un controlador de eventos
Las expresiones Lambda se pueden usar para manejar eventos, lo cual es útil cuando:
- El manejador es corto.
- El manejador nunca necesita ser cancelado.
A continuación se presenta una buena situación en la que se podría usar un controlador de eventos lambda:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");
Si es necesario cancelar la suscripción de un controlador de eventos registrado en algún punto futuro del código, la expresión del controlador de eventos se debe guardar en una variable y el registro / anulación de registro a través de esa variable:
EventHandler handler = (sender, args) => Console.WriteLine("Email sent");
smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;
La razón por la que se hace esto en lugar de simplemente volver a escribir la expresión lambda literalmente para cancelar la suscripción ( -=
) es que el compilador de C # no necesariamente considerará iguales a las dos expresiones:
EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"
Tenga en cuenta que si se agregan sentencias adicionales a la expresión lambda, entonces se pueden omitir accidentalmente las llaves circundantes requeridas, sin causar un error de tiempo de compilación. Por ejemplo:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;
Esto se compilará, pero dará como resultado la adición de la expresión lambda (sender, args) => Console.WriteLine("Email sent");
como un controlador de eventos, y ejecutando la declaración emailSendButton.Enabled = true;
inmediatamente. Para solucionar esto, el contenido de la lambda debe estar rodeado de llaves. Esto se puede evitar usando llaves desde el principio, teniendo cuidado al agregar declaraciones adicionales a un controlador de eventos lambda, o rodeando la lambda entre paréntesis desde el principio:
smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//Adding an extra statement will result in a compile-time error