Dot Net For All

C# Deferred Execution and Reevaluation in LINQ

Hello Friends, In my previous article I have discussed about the different ways we can write LINQ queries in C#. I talked about the Lambda Syntax and comprehension syntax. In this article I want to discuss one important concept of LINQ queries known as deferred execution which can help you to prevent from making silly mistakes.

Deffered execution in LINQ

LINQ queries are not evaluated the moment when we apply conditions or constructed. Instead they are executed when the result is enumerated or when MoveNext() method is called on the results.

Let’s see an example for the same.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">IList&lt;<span style="color: #333399; font-weight: bold">string</span>&gt; names = <span style="color: #008800; font-weight: bold">new</span> List&lt;<span style="color: #333399; font-weight: bold">string</span>&gt; {<span style="background-color: #fff0f0">&quot;Vikram&quot;</span>, <span style="background-color: #fff0f0">&quot;Prasad&quot;</span>, <span style="background-color: #fff0f0">&quot;Nikhil&quot;</span>, <span style="background-color: #fff0f0">&quot;Sumit&quot;</span>, <span style="background-color: #fff0f0">&quot;Varun&quot;</span> }; 
<span style="color: #333399; font-weight: bold">var</span> filteredNames = <span style="color: #008800; font-weight: bold">from</span> name <span style="color: #008800; font-weight: bold">in</span> names <span style="color: #008800; font-weight: bold">where</span> name.StartsWith(<span style="background-color: #fff0f0">&quot;V&quot;</span>) <span style="color: #008800; font-weight: bold">select</span> name;
names.Add(<span style="background-color: #fff0f0">&quot;Vijay&quot;</span>);
Console.WriteLine(filteredNames.Count());
</pre></div>

The result of the above code would be 3. As the foreach for the filteredNames collection would not be called when we apply LINQ queries on the sequence.

In other words enumeration of sequence does not takes place when filtering or sorting applied.

This is know as deffered or lazy evaluation of the sequence. All standard query operators provide deffered evaluation except:

One reason the above operators does not support deffered execution is that their result types does not support enumeration.

For example Count() returns a single digit which cannot be enumerated.

Deffered execution is important because it decouples query construction from query execution. This allows you to make a query in several steps.

Reevaluation in LINQ

Every time a sequence obtained after filtering or sorting of the original sequence is enumerated, the original sequence is considered again.

Lets see an example of the same.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">static</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">QueryOperator</span>() {
 IList&lt;<span style="color: #333399; font-weight: bold">string</span>&gt; names = <span style="color: #008800; font-weight: bold">new</span> List&lt;<span style="color: #333399; font-weight: bold">string</span>&gt; {<span style="background-color: #fff0f0">&quot;Vikram&quot;</span>, <span style="background-color: #fff0f0">&quot;Prasad&quot;</span>, <span style="background-color: #fff0f0">&quot;Nikhil&quot;</span>, <span style="background-color: #fff0f0">&quot;Sumit&quot;</span>, <span style="background-color: #fff0f0">&quot;Varun&quot;</span> };
<span style="color: #333399; font-weight: bold">var</span> filteredNames = <span style="color: #008800; font-weight: bold">from</span> name <span style="color: #008800; font-weight: bold">in</span> names <span style="color: #008800; font-weight: bold">where</span> name.StartsWith(<span style="background-color: #fff0f0">&quot;V&quot;</span>) <span style="color: #008800; font-weight: bold">select</span> name;
Console.WriteLine(filteredNames.Count()); 
names.Clear(); Console.WriteLine(filteredNames.Count()); 
Console.Read(); 
}
</pre></div>

What do you think the result of the above method.

Reevaluation in LINQ can be troublesome and can cause some serious issues.

One way to prevent from reevaluation  is to call the ToArray() or ToList() on the result sequence.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">IList&lt;<span style="color: #333399; font-weight: bold">string</span>&gt; names = <span style="color: #008800; font-weight: bold">new</span> List&lt;<span style="color: #333399; font-weight: bold">string</span>&gt; {<span style="background-color: #fff0f0">&quot;Vikram&quot;</span>, <span style="background-color: #fff0f0">&quot;Prasad&quot;</span>, <span style="background-color: #fff0f0">&quot;Nikhil&quot;</span>, <span style="background-color: #fff0f0">&quot;Sumit&quot;</span>, <span style="background-color: #fff0f0">&quot;Varun&quot;</span> };
<span style="color: #333399; font-weight: bold">var</span> filteredNames = (<span style="color: #008800; font-weight: bold">from</span> name <span style="color: #008800; font-weight: bold">in</span> names <span style="color: #008800; font-weight: bold">where</span> name.StartsWith(<span style="background-color: #fff0f0">&quot;V&quot;</span>) <span style="color: #008800; font-weight: bold">select</span> name).ToArray();
Console.WriteLine(filteredNames.Count());
names.Clear(); 
Console.WriteLine(filteredNames.Count()); Console.Read();
</pre></div>

And the result would be 2 for both of the above conditions.

I hope this article will help you to understand working of LINQ queries in .NET framework.

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview