5 votes

Comprendre le mot-clé yield et LINQ

J'essaie de mieux comprendre le mot-clé "rendement" et je pense que je le comprends assez bien. J'ai donc effectué quelques tests, mais j'ai été surpris par les résultats.

Si j'exécute le code ci-dessous, j'obtiens le résultat suivant qui montre qu'il boucle sur toute la plage et pas seulement jusqu'au numéro 4.

    public void DoIt()
    {
        Console.WriteLine("Method Call");
        var results = GetData(Enumerable.Range(1, 10));
        Console.WriteLine("LINQ");
        var filtered = results.Where(x => x == 4);
        Console.WriteLine("Start result loop");
        foreach (var item in filtered)
        {
                Console.WriteLine("Item is " + item);
        }
    }

    private IEnumerable<int> GetData(IEnumerable<int> Input)
    {
        foreach (int item in Input)
        {
            if (item % 2 == 0)
            {
                Console.WriteLine("Found " + item);
                yield return item;
            }
        }
    }

Sortie :

Method Call
LINQ
Start result loop
Found 2
Found 4
Item is 4
Found 6
Found 8
Found 10

Si j'exécute le code ci-dessous, il montre qu'il n'arrive qu'à 4 et s'arrête ensuite.

    public void DoIt()
    {
        Console.WriteLine("Method Call");
        var results = GetData(Enumerable.Range(1, 10));
        Console.WriteLine("Start result loop");
        foreach (var item in results)
        {
            if (item == 4)
            {
                Console.WriteLine("Item is " + item);
                break;
            }
        }
    }

    private IEnumerable<int> GetData(IEnumerable<int> Input)
    {
        foreach (int item in Input)
        {
            if (item % 2 == 0)
            {
                Console.WriteLine("Found " + item);
                yield return item;
            }
        }
    }

Sortie :

Method Call
Start result loop
Found 2
Found 4
Item is 4

Je suppose que je n'ai pas compris quelque chose, mais il semble que LINQ fasse le contraire de ce que j'attends de lui ? Je pensais que LINQ utilisait aussi le yield et l'exécution différée et je m'attendrais à ce que les résultats du second jeu de code soient les mêmes que ceux du premier jeu de code.

12voto

thecoop Points 23695

Il utilise l'exécution différée. LINQ Where vérifie tous les éléments de l'énumérable d'entrée, il ne s'arrête pas quand il arrive au premier élément trouvé. C'est ce que First fait.

Votre premier exemple renverrait la même chose que le second si vous changiez Where à First ou si vous avez retiré le break du deuxième exemple.

2voto

Mithrandir Points 10545

Je pense que vous vous trompez dans votre logique de base, pas dans LINQ. Votre premier exemple doit itérer sur l'ensemble de la plage, car la condition where doit trouver toutes les valeurs qui sont égales à 4, et pas seulement la première valeur, qui est égale à 4.

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