Introduction

IEnumerable<T>, yield et Where

07/12/2011 316 lectures 0 commentaire 4/5 (2 votes)

Introduction

LINQ (Language Integrated Query) est une nouveauté apportée par le Framework 3.5. Ce composant va permettre, dans les grandes lignes, de faire des requêtes sur des collections d’objet de tout type. Ainsi, il sera possible de faire des requêtes sur des collections d’objet « en mémoire », mais également sur des documents XML ou sur des tables SQL. Dans le cadre de cette introduction, nous allons principalement nous concentrer sur l’aspect « en mémoire ».

yield

Avant de parler de LINQ, nous allons nous intéresser au mot-clé « yield ». Bien que méconnu, « yield » est très intéressant et totalement indispensable dans le fonctionnement de LINQ. Imaginez par exemple le code suivant :


Nous commençons par créer une classe « Student » qui servira à contenir des informations sur des étudiants. Dans notre classe statique, nous allons faire une méthode qui permettra de parcourir cette collection et d’en récupérer les étudiants majeurs. Nous constituons alors une collection temporaire que nous renverrons à la fonction appelante qui se charge d’afficher ces étudiants. Ici, rien de bien compliqué.

Remplacez maintenant la fonction « GetOfAge » par ceci :


Ici, nous utilisons le mot-clé « yield » pour renvoyer les données que nous voulons. Bien que « yield » soit suivi de « return », la méthode ne sera pas terminée lorsque ce mot-clé sera rencontré, en effet, l’élément sera juste renvoyé. Outre le fait qu’une collection temporaire n’est plus requise, il y a un avantage à utiliser « yield » : cela permet de faire des requêtes différées. Autrement dit, cette fonction ne renverra pas de valeur lors de son appel mais plutôt lors de son utilisation. Pour comprendre cela, modifiez la méthode « main » de cette façon :


Et rajoutez également une ligne dans la fonction « GetOfAge » comme ceci :


Si vous exécutez votre application, la sortie à l’écran sera la suivante :

Image


Comme vous le voyez, les lignes « Before GetOfAge » et « After GetOfAge » s’affichent l’une à la suite de l'autre. Effectivement, lorsque la méthode va être appelée, elle ne va pas vraiment être exécutée, elle ne le sera que lorsque l’on utilisera. Dans notre cas, nous l’utilisons lorsque nous parcourons la collection qu'elle renvoie pour en afficher le contenu. Dans ce cas, la méthode sera exécutée et c’est pour cela que « GetOfAge » s’affiche avant « End ».

Le mot-clé « yield » peut également être suivi du mot-clé « break » pour sortir de la boucle et donc arrêter de renvoyer des valeurs. C’est le « même break » que celui que l’on peut utiliser dans une boucle « for » ou « foreach », je ne m’étendrai donc pas sur le sujet.

IEnumerable

« IEnumerable » est une interface implémentée par toutes les collections d’objet génériques dans C#. C’est grâce à cette interface que « LINQ » pourra être utilisé. En effet, LINQ (contenu dans le « namespace System.Linq ») n’est qu’un ensemble de fonctions d’extension appliquées à l’interface « IEnumerable<T> ». Vous pourrez donc appeler des méthodes « LINQ » sur presque n’importe quelle collection à partir du moment où celle-ci implémente l’interface « IEnumerable<T> ».

Nous verrons que pour toutes les collections n’implémentant pas cette interface, il est possible de les « convertir » en « IEnumerable<T> » en utilisant les méthodes « Cast » ou « OfType ».

LINQ

Nous allons maintenant voir à quoi peut bien servir « LINQ » mais également ce qui se cache derrière les fonctions LINQ. Pour cette introduction, nous allons voir brièvement l’utilisation de la méthode « Where ». Pour cela, nous allons supprimer la méthode « GetOfAge » et remplacer le contenu de notre fonction « main » par ceci :


Si vous exécutez votre application, vous verrez que le résultat est exactement le même que précédemment. Ce bout de code nous permet de récupérer tous les étudiants âgés de plus de 17 ans. La fonction « Where » permet simplement de récupérer des objets depuis une collection selon un critère spécifique. Le critère en question sera passé sous la forme d’un « Func » prenant en entrée un objet du type de la collection (donc pour une liste générique contenant des « string », ce sera « string ») et renvoyant un « booléen » permettant d’indiquer que l’objet en question doit être retournée ou non. Par exemple, nous aurions très bien pu récupérer tous les étudiants ayant un âge pair comme ceci :


Encore une fois, la variable « s » sera du type « Student » (car la liste contient des objets de type « Student ») et la fonction renverra un booléen. A première vue, cela semble absolument extraordinaire et compliqué, mais si nous réfléchissons, la fonction « Where » est d’une simplicité enfantine. Voici le code de celle-ci (celui-ci ne sera pas le code exact mais une possibilité de code). Pour la tester, veillez supprimer la clause « using System.Linq ». Ainsi, Visual Studio ne trouvera plus la fonction d’extension « Where » de « LINQ » mais bien celle que nous allons implémenter.


La fonction « Where » est donc une fonction d’extension générique appliquée sur les objets d’un type implémentant l’interface « IEnumerable<T> ». Le deuxième paramètre de cette fonction est un « Func » permettant de faire une sélection. Nous parcourons ensuite la collection et ne renvoyons (grâce à « yield ») que les objets pour lesquels le « Func » renvoie « true ». Le listing complet de notre application est le suivant :


Vous voyez donc que la fonction « Where » est aussi simple qu’utile. Dans les prochains cours, nous verrons comment utiliser les principales fonctions de « LINQ ».

Voter :

0 commentaires

Ajouter un commentaire