Reputation: 2719
For instance
myEnumerable.Where(v => v != myDictionary["someKey"])
when this query is called is myDictionary["someKey"]
statement executed (meaning that dictionary is queried for the key) or the result of myDictionary["someKey"]
is used after the first iteration?
Upvotes: 3
Views: 140
Reputation: 14477
The result of myDictionary["someKey"]
will not be cached(*see edit below), it will be accessed on every item of myEnumerable
. However, you can still cache it manually :
var someValue = myDictionary["someKey"];
myEnumerable.Where(v => v != someValue)
Also take note that, if you plan to iterate/access that IEnumerable
multiple time, it is best to actualize it via ToList()
. Or, the execution will be deferred every single time.
var query = myEnumerable.Where(v => v != myDictionary["someKey"]);
foreach (var item in query) { /* ... */}
foreach (var item in query) { /* ... */}
In the above example, the Where
clause is executed twice.
EDIT: As @LucasTrzesniewski has pointed out, this is only stands true for LINQ-to-Objects
. This is because the query is evaluated in memory. However, for LINQ-to-Entities
, it gets a little bit different, as the query will be converted into SQL query and then executed in the database in order to avoid round trips.
Upvotes: 6
Reputation: 30995
It depends on the QueryProvider implementation. For example, the ObjectQueryProvider used by Linq-to-objects will access it on every iteration. For Linq-to-entities, it will access it once and then send that value to the database server.
Upvotes: 0
Reputation: 45135
Here's a really simple demo (and please, don't try this at home):
var myDictionary = new Dictionary<string,string>() { { "someKey", "someValue" } };
var myEnumerable = new List<string> { "someValue", "someOtherValue" };
var test = myEnumerable.Where(v => v == myDictionary["someKey"]);
foreach (var t in test)
{
Console.WriteLine(t);
myDictionary["someKey"] = "someOtherValue";
}
If myDictionary["someKey"]
was only evaulated once, then changing the value of myDictionary["someKey"]
wouldn't change anything. But if you run the code, you will see that it will echo both someValue
and someOtherValue
. If you comment out the line that changes the dictionary value, then you will only see someValue
As @Lucas Trzesniewski points out in the comments to the other answer, this applies to LINQ-to-objects. There are a number of important differences between LINQ-to-objects and LINQ-to-SQL.
Upvotes: 1
Reputation: 2792
The Lambda expression you supply to the Linq Where
extension is simply a Func<> delegate. The method is executed for each item in the IEnumerable(of T), receiving the current item as a parameter. It doesn't do anything special other than that. Your code is somewhat similar similar to:
var myTempCollection = new List<MyClass>();
foreach(MyClass item in myEnumerable)
{
if (item != myDictionary["someKey"])
{
myTempCollection.Add(item);
}
}
var result = myTempCollection;
Upvotes: 0