Deferred


[.NET] Linq et type dynamique, attention au piège en .NET

2012-12-18 4 Min. lecture .NET

Problème

Le code suivant affiche « Numbers greater than 3 are : 6 7 » au lieu du « Numbers greater than 3 are : 4 5 6 7 » attendu.

Savez-vous pourquoi ?

class Program
{
    static void Main(string[] args)
    {
        List<Int32> allNumbers = new List<Int32>() { 1, 2, 3, 4, 5, 6, 7 };

        List<dynamic> greaterNumbers = new List<dynamic>();
    
        // Finding all numbers from the "allNumbers" list that are greater 
        // than "currentNumber"
        for (Int32 currentNumber = 0; currentNumber < 5; currentNumber++)
        {
            dynamic item = new ExpandoObject();
            item.Number = currentNumber;
            item.GreaterNumbers = allNumbers.Where(e => e > currentNumber);
            greaterNumbers.Add(item);
        }
        // Here greaterNumbers contains 5 items
    
        // We want to display numbers greater than 3
        dynamic greaterThan3 = greaterNumbers
                               .FirstOrDefault(i => i.Number == 3);
    
        if (greaterThan3 != null)
        {
            Console.Write("Numbers greater than 3 are : ");
            foreach (Int32 greaterNumber in greaterThan3.GreaterNumbers)
            {
                Console.Write(greaterNumber);
                Console.Write(' ');
            }
            Console.WriteLine();
        }
    }
}

Explication

Where, est une méthode d’extension proposée par LINQ. Cette méthode s’exécute en différé, c’est-à-dire que le Where ne sera exécuté que lorsqu’on voudra accéder à son résultat. Cette exécution différée est causée par la présence du mot clé « yield » dans l’implémentation de la méthode Where.

continuer la lecture