171 votes

Pourquoi utiliser le mot clé yield, quand je pourrais juste utiliser un IEnumerable ordinaire ?

Compte tenu de ce code :

Pourquoi devrais je non seulement coder ça ? :

J’ai sorte de comprendre ce qu’est le `` mot clé. Il indique au compilateur de générer un certain genre de chose (un itérateur). Mais pourquoi l’utiliser ? Mis à part qu’il soit un peu moins de code, c’est quoi faire pour moi ?

239voto

Robert Harvey Points 103562

À l’aide de `` rend la collection paresseux.

Disons que vous avez juste besoin des cinq premiers éléments. Votre chemin, je dois effectuer une boucle sur l' ensemble de la liste pour obtenir les cinq premiers éléments. Avec `` , j’ai seulement effectuer une boucle sur les cinq premiers éléments.

127voto

Jon Skeet Points 692016

L'avantage de l'itérateur blocs est qu'ils travaillent paresseusement. Vous pouvez donc écrire une méthode de filtrage comme ceci:

public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
                                   Func<T, bool> predicate)
{
    foreach (var item in source)
    {
        if (predicate(item))
        {
            yield return item;
        }
    }
}

Qui va vous permettre de filtrer les flux aussi longtemps que vous le souhaitez, jamais mise en mémoire tampon plus qu'un seul élément à la fois. Si vous avez besoin seulement la première valeur de la séquence retournée, par exemple, pourquoi voulez-vous copier tout dans une nouvelle liste?

Comme autre exemple, vous pouvez facilement créer un infini de flux à l'aide d'itérateur blocs. Par exemple, voici une séquence aléatoire de nombres aléatoires:

public static IEnumerable<int> RandomSequence(int minInclusive, int maxExclusive)
{
    Random rng = new Random();
    while (true)
    {
        yield return rng.Next(minInclusive, maxExclusive);
    }
}

Comment voulez-vous stocker une séquence infinie dans une liste?

Mon Edulinq blog de la série donne un exemple de mise en œuvre de LINQ to Objects qui les rend lourd utilisation de l'itérateur de blocs. LINQ est fondamentalement paresseux où il peut être - et de mettre les choses dans une liste simplement ne fonctionne pas de cette façon.

42voto

Hans Kesting Points 17043

Avec le code « list », vous devez traiter la liste la plus complète avant que vous pouvez passer à l’étape suivante. La version de « rendement » lui passe l’élément transformé immédiatement à l’étape suivante. Si cette « prochaine étape » contient un «. Take(10) » puis la version de « rendement » seulement traitera les 10 premiers éléments et oublier le reste. Le code de « liste » serait a traité en tout.

Cela signifie que vous voyez le plus de différence lorsque vous devez faire beaucoup de traitement et/ou ont de longues listes de points à traiter.

23voto

Jason Whitted Points 2763

Vous pouvez utiliser `` pour retourner les éléments qui ne sont pas dans une liste. Voici un petit échantillon qui pouvait parcourir une liste jusqu'à annulation et infiniment.

Cela écrit

... etc à la console jusqu'à annulation.

10voto

kpadmanabhan Points 1028
<pre><code></code><p><code></code>produira deux fois. Il s’agit d’un comportement paresseux.</p><p>Où que la méthode à l’aide de la liste ajoutera tous les objets n à la liste et transmettez la liste complète à la méthode appelante.</p><p>Il s’agit d’exactement un cas d’utilisation où la différence entre IEnumerable et IList peut être soulignée.</p></pre>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X