Expresiones lambda

Elija una expresión lambda cuando desee pasar una operación corta a otro método y la operación sea más clara junto a la llamada que la usa. Una regla insertada muestra a los lectores cómo se seleccionan o transforman elementos; un método con nombre les permite seguir el propósito de la operación antes de inspeccionar sus detalles.

Tip

En este artículo se enseñan opciones prácticas para desarrolladores que conocen los métodos y colecciones de C#. Para obtener la sintaxis y las reglas lambda completas, consulte la referencia de expresiones lambda.

Una expresión lambda es una función sin nombre que se escribe donde otro fragmento de código necesita comportamiento.

La expresión lambda siguiente acepta una sesión y devuelve si la sesión tiene puestos abiertos:

session => session.Registered < session.Capacity

El => operador separa los parámetros de la izquierda del cuerpo de la derecha. Léelo como "va a".

Pasar el comportamiento a un método

Muchas .NET API aceptan un delegado, que es un tipo que representa el comportamiento con una lista de parámetros determinada y un tipo de valor devuelto. Una expresión lambda proporciona ese comportamiento. Para obtener una introducción a los tipos delegados, como Func y Action, vea Expresiones lambda, delegados y eventos.

En el ejemplo siguiente se trabaja con sesiones de taller. WorkshopSession Contiene un título, una duración, una capacidad y un recuento de registros.

int maximumMinutes = 60;

var shortSessions = sessions
    .Where(session => session.DurationMinutes <= maximumMinutes)
    .OrderBy(session => session.Title);

foreach (WorkshopSession session in shortSessions)
{
    Console.WriteLine(session.Title);
}

La primera expresión lambda indica Where qué sesiones se van a conservar. El segundo indica OrderBy por qué valor se va a ordenar. Los métodos reciben el comportamiento sin conocer los detalles de ninguna de las reglas.

Elección de un formulario de parámetros

Elija el formulario de parámetro más corto que permanezca claro:

session => session.DurationMinutes <= 60

Para un parámetro, omita paréntesis cuando el compilador pueda deducir el tipo. Use paréntesis vacíos para ningún parámetro:

() => DateTime.Now

Use paréntesis para dos o más parámetros:

(left, right) => left + right

Normalmente, el método que recibe la expresión lambda proporciona suficiente información para que el compilador infiere los tipos de parámetros. Escriba tipos explícitos cuando la inferencia necesite ayuda o cuando los tipos mejoren la claridad:

(WorkshopSession session) => session.Title

La referencia de expresiones lambda abarca modificadores de parámetros, atributos, valores predeterminados y otros formularios especializados.

Elegir un cuerpo de expresión o instrucción

Use una expresión lambda cuando una expresión calcule el resultado:

session => session.Registered < session.Capacity

Use una expresión lambda de instrucción cuando la operación necesite más de una instrucción. Incluya el cuerpo entre llaves e incluya return cuando la lambda devuelva un valor:

var descriptions = sessions.Select(session =>
{
    int seatsLeft = session.Capacity - session.Registered;
    string availability = seatsLeft > 0 ? $"{seatsLeft} seats left" : "full";
    return $"{session.Title}: {availability}";
});

Console.WriteLine(string.Join(Environment.NewLine, descriptions));

Mantenga breves expresiones lambda de instrucción. Cuando el cuerpo necesita varios pasos o la misma lógica aparece más de una vez, asigne al comportamiento un nombre descriptivo con una función local o un método normal.

Captura de valores del ámbito circundante

Una expresión lambda puede usar una variable declarada en el método circundante. Este uso se denomina captura. En el primer ejemplo, la expresión lambda de selección captura maximumMinutes:

int maximumMinutes = 60;
var shortSessions = sessions.Where(
    session => session.DurationMinutes <= maximumMinutes);

La captura ayuda a una regla corta a usar el contexto local. La expresión lambda captura la propia variable, no una copia de su valor. Si la variable cambia antes de que se ejecute la expresión lambda, la expresión lambda ve el valor actual.

Facilitar la identificación del contexto necesario. Si una expresión lambda no necesita un estado circundante, agregue static para evitar la captura accidental y hacer que esa independencia sea visible para los lectores:

var openSessions = sessions.Where(
    static session => session.Registered < session.Capacity);

Una expresión lambda estática puede usar sus parámetros, valores que declara, constantes y miembros estáticos. No puede usar variables locales ni estado de instancia desde el código circundante.

Elección de una función lambda, grupo de métodos o local

Varios formularios de C# pueden proporcionar comportamiento a un parámetro delegado:

  • Use una expresión lambda para un comportamiento corto que lea claramente junto a la llamada.
  • Use un grupo de métodos cuando un método existente tenga la firma necesaria y su nombre explica el comportamiento.
  • Use una función local cuando el miembro contenedor necesite lógica con nombre reutilizable, recursividad o un cuerpo demasiado grande para una lambda insertada.
  • Use un método normal cuando varios miembros necesiten el comportamiento.

Un grupo de métodos es un nombre de método sin su lista de argumentos. El compilador convierte el método coincidente en el tipo de delegado necesario:

var openSessions = sessions.Where(HasOpenSeats);

foreach (WorkshopSession session in openSessions)
{
    Console.WriteLine($"Open: {session.Title}");
}

static bool HasOpenSeats(WorkshopSession session) =>
    session.Registered < session.Capacity;

Where(HasOpenSeats) comunica la misma regla que Where(session => HasOpenSeats(session)) con menos código. El nombre del método indica a los lectores qué prueba la regla; Una comparación insertada muestra cómo prueba esa regla. Mantenga el contenedor lambda cuando agrega un argumento, combina operaciones o hace que la llamada sea más clara.

Para obtener una comparación local detallada, consulte Funciones locales.

Consulte también