JKennedy
JKennedy

Reputation: 18799

Does using a LINQ statement in a foreach re-evaluate the statement on each iteration

So what I am wondering is whether using a LINQ where clause in my foreach loop means that on each iteration it will re-evaluate my LINQ where clause. For example:

var MyId = 1;
foreach (var thing in ListOfThings.Where(x => x.ID == MyId))
{ 
  //do Something
}

or is it better to write:

var MyId = 1;

var myList = ListOfThings.Where(x => x.ID == MyId);
foreach (var thing in myList)
{ 
  //do Something
}

or are they both work in exactly the same way?

Upvotes: 1

Views: 1297

Answers (3)

Gusdor
Gusdor

Reputation: 14334

This sample should give you all the answers you seek:

Code

using System;
using System.Linq;

public class Test
{
    public static void Main()
    {
        // Create sequence of integers from 0 to 10
        var sequence = Enumerable.Range(0, 10).Where(p => 
        { 
            // In each 'where' clause, print the current item.
            // This shows us when the clause is executed
            Console.WriteLine(p); 

            // Make sure every value is selected
            return true;
        });

        foreach(var item in sequence)
        {
            // Print a marker to show us when the loop body is executing.
            // This helps us see if the 'where' clauses are evaluated 
            // before the loop starts or during the loop
            Console.WriteLine("Loop body exectuting.");
        }
    }
}

Output

0
Loop body exectuting.
1
Loop body exectuting.
2
Loop body exectuting.
3
Loop body exectuting.
4
Loop body exectuting.
5
Loop body exectuting.
6
Loop body exectuting.
7
Loop body exectuting.
8
Loop body exectuting.
9
Loop body exectuting.

Conclusion

The Where clause is evaluated once, for the current element, at the start of each loop iteration.

Upvotes: 1

Jerry Federspiel
Jerry Federspiel

Reputation: 1524

foreach (var thing in myExpression) calls myExpression.GetEnumerator and MoveNexts until it returns false. So your two snippets are the same.

(Incidentally, GetEnumerator is a method on IEnumerable, but myExpression doesn't have to be an IEnumerable; just a thing with a GetEnumerator method).

Upvotes: 2

JKennedy
JKennedy

Reputation: 18799

So from the comments I have worked out that the foreach loop does not re-evaluate my LINQ where on each iteration.

From MSDN Enumerable.Where I can see that this method returns an IEnumerable

Return Value Type: System.Collections.Generic.IEnumerable An IEnumerable that contains elements from the input sequence that satisfy the condition.

That is then iterated over in the foreach loop

Upvotes: 0

Related Questions