Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq deferred execution with local values

Tags:

c#

.net

list

linq

I've been experimenting with Linq to see what it can do - and I'm really loving it so far :)

I wrote some queries for an algorithm, but I didn't get the results I expected... the Enumeration always returned empty:

case #1

List<some_object> next = new List<some_object>();
some_object current = null;

var valid_next_links =
    from candidate in next
    where (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime)
    orderby candidate.fromTime
    select candidate;

current = something;
next = some_list_of_things;

foreach (some_object l in valid_next_links)
{
    //do stuff with l
}

I changed the query declaration to be inline like this, and it worked fine:

case #2

 foreach (some_object l in
      (from candidate in next
       where (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime)
       orderby candidate.fromTime
       select candidate))
 {
  //do stuff with l
 }

Does anybody know why it doesn't work in case #1 ? The way I understood it, the query wasn't evaluated when you declared it, so I don't see how there is a difference.

like image 611
Oofpez Avatar asked Jun 19 '12 13:06

Oofpez


People also ask

What are the benefits of a deferred execution in LINQ?

Benefits of Deferred Execution –It avoids unnecessary query execution and hence improves performance. Query construction and Query execution are decoupled, so we can create the LINQ query in several steps. A deferred execution query is reevaluated when you re-enumerate – hence we always get the latest data.

What is deferred execution in LINQ?

LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results.

What is deferred execution vs immediate execution in LINQ?

The basic difference between a Deferred execution vs Immediate execution is that Deferred execution of queries produce a sequence of values, whereas Immediate execution of queries return a singleton value and is executed immediately.

What is meant by deferred execution?

Deferred execution means that the evaluation of an expression is delayed until its realized value is actually required. It greatly improves performance by avoiding unnecessary execution.


1 Answers

Changes to current will be captured, but the query already knows the value of next. Adding extra items to the existing list will make them show up in the query, but changing the value of the variable to refer to a different list entirely won't have any effect. Basically, if you mentally expand the query from a query expression into a "normal" form, any variable present in a lambda expression will be captured as a variable, but any variable present directly as an argument will be evaluated immediately. That will only capture the reference value of the variable, not the items present in the list, but it still means changing the variable value itself won't be seen. Your first query expands to:

var valid_next_links = next
      .Where(candidate => (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime))
      .OrderBy(candidate => candidate.fromTime);
like image 100
Jon Skeet Avatar answered Oct 27 '22 01:10

Jon Skeet