Expressions lambda

Choisissez une expression lambda lorsque vous souhaitez passer une opération courte à une autre méthode et que l’opération est la plus claire à côté de l’appel qui l’utilise. Une règle inline montre aux lecteurs comment vous sélectionnez ou transformez des éléments ; une méthode nommée leur permet de suivre l’objectif de l’opération avant d’inspecter ses détails.

Tip

Cet article explique les choix pratiques pour les développeurs qui connaissent les méthodes et collections C#. Pour obtenir la syntaxe et les règles lambda complètes, consultez la référence des expressions lambda.

Une expression lambda est une fonction sans nom que vous écrivez où un autre élément de code a besoin d’un comportement.

L’expression lambda suivante accepte une session et retourne si la session a des places disponibles :

session => session.Registered < session.Capacity

L’opérateur => sépare les paramètres à gauche du corps de la fonction à droite. À lire « va à ».

Transmettre un comportement à une méthode

De nombreuses API .NET acceptent un délégué, qui est un type qui représente le comportement avec une liste de paramètres et un type de retour particulier. Un lambda permet ce comportement. Pour une introduction aux types délégués tels que Func et Action, consultez les expressions lambda, les délégués et les événements.

L’exemple suivant fonctionne avec des sessions d’atelier. Un WorkshopSession contient un titre, une durée, une capacité et un nombre d’inscriptions.

int maximumMinutes = 60;

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

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

Le premier lambda indique à Where quelles sessions conserver. La deuxième indique à OrderBy selon quelle valeur trier. Les méthodes reçoivent le comportement sans connaître les détails de l’une ou l’autre règle.

Choisir un formulaire de paramètres

Choisissez la forme de paramètre la plus courte qui reste claire :

session => session.DurationMinutes <= 60

Pour un paramètre, omettez les parenthèses lorsque le compilateur peut déduire le type. Utilisez des parenthèses vides lorsqu’il n’y a aucun paramètre :

() => DateTime.Now

Utilisez des parenthèses pour deux paramètres ou plus :

(left, right) => left + right

En règle générale, la méthode qui reçoit le lambda fournit suffisamment d’informations pour que le compilateur déduise les types de paramètres. Écrivez des types explicites lorsque l’inférence a besoin d’aide ou lorsque les types améliorent la clarté :

(WorkshopSession session) => session.Title

La référence des expressions lambda couvre les modificateurs de paramètres, les attributs, les valeurs par défaut et d’autres formes spécialisées.

Choisissez un corps d’expression ou d’instruction

Utilisez une expression lambda quand une expression calcule le résultat :

session => session.Registered < session.Capacity

Utilisez une lambda d’instructions lorsque l’opération a besoin de plusieurs instructions. Placez le corps dans les accolades et incluez return lorsque l’expression lambda retourne une valeur :

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));

Gardez les lambdas d’instruction brèves. Lorsque le corps a besoin de plusieurs étapes ou lorsque la même logique apparaît plusieurs fois, donnez au comportement un nom descriptif avec une fonction locale ou une méthode régulière.

Capturer des valeurs depuis la portée englobante

Un lambda peut utiliser une variable déclarée dans la méthode environnante. Cette utilisation est appelée capture. Dans le premier exemple, la sélection lambda capture maximumMinutes:

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

Capture aide une règle courte à utiliser le contexte local. L’expression lambda capture la variable elle-même, et non une copie de sa valeur. Si la variable change de valeur avant l’exécution de la lambda, l’expression lambda voit la valeur actuelle.

Identifiez facilement le contexte requis. Si une lambda n’a pas besoin d’un état environnant, ajoutez static pour empêcher la capture accidentelle et rendre cette indépendance visible par les lecteurs :

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

Une lambda statique peut utiliser ses paramètres, valeurs qu’elle déclare, constantes et membres statiques. Il ne peut pas utiliser les variables locales ou l’état de l’instance à partir du code environnant.

Choisir une fonction lambda, un groupe de méthodes ou une fonction locale

Plusieurs formes C# peuvent fournir un comportement à un paramètre delegate :

  • Utilisez une expression lambda pour un comportement court qui reste clair à la lecture à côté de l’appel.
  • Utilisez un groupe de méthodes si une méthode existante a la signature requise et que son nom explique le comportement.
  • Utilisez une fonction locale lorsque le membre conteneur a besoin d’une logique nommée réutilisable, d’une récursivité ou d’un corps trop volumineux pour un lambda inline.
  • Utilisez une méthode normale lorsque plusieurs membres ont besoin de ce comportement.

Un groupe de méthodes est un nom de méthode sans sa liste d’arguments. Le compilateur convertit la méthode compatible en type délégué requis :

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) exprime la même règle que Where(session => HasOpenSeats(session)), avec moins de code. Le nom de la méthode indique aux lecteurs ce que la règle teste ; une comparaison inline montre comment elle teste cette règle. Conservez le wrapper lambda lorsqu’il ajoute un argument, combine des opérations ou rend l’appel plus clair.

Pour obtenir une comparaison locale détaillée, consultez Les fonctions locales.

Voir également :