LINQ: Deferred Execution

The following example shows how query execution is deferred until the results is enumerated.

 static void TryLinq()
 {
     int i = 0;
     int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

     // fake values for the query only (10 values)

     var result = from n in numbers select Increment(ref i);

     Console.WriteLine("After query i = {0}", i); // i still 0

     Console.WriteLine();

     Console.WriteLine("Enumerating results:");
     foreach (var v in result)
     {
         Console.WriteLine("v = {0},ti = {1}", v, i);
         // i is incremented every loop
     }

     Console.WriteLine("Press any key to continue . . .");
     Console.ReadKey(true);

     // Result:-

     // After query i = 0
     //
     // Enumerating results:
     // v = 1,  i = 1
     // v = 2,  i = 2
     // .............
     // v = 9,  i = 9
     // v = 10, i = 10

     // What you get?
     // Deferred-Execution / Lazy-Execution
     // - Query doesn't execute until you
     //   begin retrieving it's results.
     // - Every time you try get a value
     //   the query executes on this value only.
 }

 static int Increment(ref int i) { return ++i; }

Next is an example shows how you can execute the query immediately.

static void TryLinq()
{
    int i = 0;
    int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    // fake values for the query only (10 values)

    var result =
        (from n in numbers select Increment(ref i)).ToList();
    // The last call tries to get the value immediately.

    Console.WriteLine("After query i = {0}", i); // i is 10

    Console.WriteLine();

    Console.WriteLine("Enumerating results:");
    foreach (var v in result)
    {
        Console.WriteLine("v = {0},ti = {1}", v, i);
        // i still 10 every loop
    }

    Console.WriteLine("Press any key to continue . . .");
    Console.ReadKey(true);

    // Result:-

    // After query i = 10
    //
    // Enumerating results:
    // v = 1,  i = 10
    // v = 2,  i = 10
    // .............
    // v = 9,  i = 10
    // v = 10, i = 10

    // What you get?
    // Deferred-Execution / Lazy-Execution
    // - Query doesn't execute until you
    //   begin retrieving it's results.
    // - Every time you try get a value the
    //   query executes on this value only.
    // - You can immediate-execute the query by
    //   calling some conversation methods like
    //   ToList or ToQuery.
}

static int Increment(ref int i) { return ++i; }

What you get?
Deferred-Execution / Lazy-Execution

  • Query doesn’t execute until you begin retrieving it’s results.
  • Every time you try get a value the query executes on this value only.
  • You can execute the query immediately by calling a conversation method like ToList() or ToQuery().