An important part of LINQ and C# 3.0 is the concept of deferred execution. What does this mean?
Let's have a look at the following code:
static void Main( string[] args )
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var evenNumbers = numbers.Select( x => ( x % 2 == 0 ) );
foreach ( int i in evenNumbers )
{
if ( i == 6 )
numbers.Add( 12 ); // add a number to the list of numbers
Console.WriteLine( i );
}
Console.ReadLine();
}
public static List<int> Select( this List<int> numbers, Filter filter )
{
List<int> result = new List<int>();
foreach ( int i in numbers )
{
// call the filter method/delegate to see if this
// number needs to be in the result
if ( filter( i ) == true )
{
// if i matches the filter then add it to the result
result.Add( i );
}
}
return result;
}
In the code above the extension method 'Select' will apply a filter and return a subset of the original collection of numbers. When the numbers are printed we add the number '12' to the original collection. Since the Select method created a new collection with the subset we will not see the number 12 being printed to the console. If we want a more dynamic interaction we can rewrite the Select method to return an enumerator rather than a List.
public static IEnumerable<int> Select( this List<int> numbers, Filter filter )
{
for ( int n = 0; n < numbers.Count; n++ )
{
if ( filter( numbers[n] ) == true )
{
// if numbers[n] matches the filter then yield the value
yield return numbers[n];
}
}
}
The code above shows that instead of returning a List of numbers we now yield the value of each number as it passes through the filter. Now when we run the same Main we will see that the value '12' is included in our output. If we put a breakpoint inside the application we can inspect the type of 'evenNumbers'.

As you can see it point to the Select methods and the Lambda has been compiled into an anonymous delegate. Rather than having a fixed result the Select method keeps being called until there are no more numbers being 'yielded'. You can preview the results by opening the 'Results View', but that will only provide a view of the iterator at that specific point in time.