Les expressions Lambda ont été introduites dans C#3 (.NET 3.5). Ces expressions sont aujourd’hui utilisées un peu partout dans le code, pour faire des requêtes LINQ, pour faire des filtres sur des listes, pour des délégués et des évènements.
Il est donc essentiels de bien comprendre le fonctionnement de ce type d’expression.
Qu’est ce qu’une expression Lambda ?
Une expression lambda est une fonction anonyme qui peut contenir des expressions et des instructions. Elle peut ainsi utilisée pour créer des délégués ou des types d’arborescence d’expression.
Toutes les expressions utilisent l’opérateur lambda => (se lit « conduit à »).
Une expression est toujours constituée de deux parties :
- le côté gauche donne les paramètres d’entrées (s’il y en a),
- le côté doit donne les instructions de la méthode anonyme.
Les expressions lambda sont utilisées de deux manières :
- pour créer des lambda-expression : il s’agit d’expression qui sont utilisée pour créer des arborescences d’expressions (surtout utilisé pour exécuter des instructions dynamiquement, idéal pour créer des filtres de données avec Linq par exemple),
- pour créer des lambda-instructions : il s’agit de l’équivalent d’un delegate en C# avec une syntaxe différente.
Exemples
Voici un exemple de Lambda-expression
[csharp] delegate int DelegateType(int i);public void Main()
{
DelegateType myDelegate = x => x*x;
int square = myDelegate(5); // square vaut 25
}
[/csharp]
Voici un exemple de Lambda-instruction
[csharp] delegate void DelegateInstruction(string s);public void Main()
{
DelegateInstruction myFunc = str => { Console.WriteLine("Entree = {0}", str); };
myFunc("Hello"); // affiche "Entree = Hello"
}
[/csharp]
Utiliser les expressions lambda au quotidien
Les bases
Le framework .NET propose de nombreuses méthodes qui utilisent les expressions lambda au travers du type Func.
Les délégués Func sont des délégués paramétrés qui permettent de spécifier le type en entrée (T) et le type en sortie (TResult).
Ces délégués sont très utiles pour encapsuler des expressions définies par l’utilisateur afin de les appliquer à une source de données.
Ce délégué est défini comme ceci :
[csharp] public delegate TResult Func(TArg0 arg0)[/csharp]
En reprennant l’exemple précédent, celui du calcul du carré, il est possible d’écrire ce morceau de code à la place :
[csharp] public void Main(){
Func<int,int> myDelegate = x => x*x;
int square = myDelegate(5); // square vaut 25
}
[/csharp]
Ok, c’est exemple est simple. Mais allons plus loin. Le framework propose beaucoup de méthodes d’extensions depuis l’apparition de Linq.
La plus utilisée est sans doute Count qui permet de retourner le nombre d’éléments d’une collection.
Cette méthode supporte plusieurs surcharges dont une qui propose une paramètre du type Func, ce qui permet de spécifier une expression de filtrage.
Grâce à ce mécanisme, il est possible de compter certains éléments en particulier.
Voici un exemple :
[csharp] int[] nombres = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};public void Main()
{
// Calcule le nombre d’éléments pairs dans la liste
int pairs = nombres.Count(n => n % 2 == 0);
}
[/csharp]
Voici un autre exemple, utilisant la méthode Average :
[csharp] // Retourne la moyenne des nombres de la liste// (dont chacun est supérieur à 5)
int moyenne = nombres.Average(n => n>5);
[/csharp]
Application de filtres consécutifs
Prenons l’exemple d’une liste d’éléments que nous souhaitons filtrer (par exemple, une liste d’utilisateur).
Les expressions lambda permettent d’appliquer plusieurs filtres sur des collections.
{
// délégué pour garder uniquement les éléments non vides
Func filtreVide = s => !String.IsNullOrEmpty(s);
// délégué pour garder les éléments qui contiennent une "a" ou un "b"
Func filtreLettres = s => s.Contains(‘a’) || s.Contains(‘b’);
List utilisateurs = new List();
utilisateurs.AddRange(new string[] { "", null, "pascal", "john" });
// application du 1er filtre
IEnumerable resultat = utilisateurs.Where(filtreVide);
// application du 2nd filtre
resultat = resultat.Where(filtreLettres);
// affichage du résultat
foreach (var item in resultat)
Console.WriteLine(item);}
[/csharp]
Conclusion
Les expressions lambda sont aujourd’hui très utilisées dans le framework .NET. Il est quasi-impossible de s’en passer (beaucoup de composants les utilisent).
Je vous invite donc à essayer et à utiliser ces mécanismes.
Pour aller plus loin, vous pouvez aussi vous informer sur les arborescences d’expressions qui permettent de créer des méthodes compilées à la volée pour calculer des expressions : Voir sur le site de Microsoft.
bjr, enfin j’ai compris comment ça marche, encore merci!
Bonjour, je suis content d’avoir pu vous aider !
Simple intro bien efficace. Juste à revoir le code qui ne marche pas à certains endroit.
Comme le cas du functor générique :
Func myDelegate = x => x * x;
Merci, je viens de corriger (c’est bien sûr Func et non pas Func).