Trouble understanding yield in C#
This is called deferred execution, yield
is lazy and will only work as much as it needs to.
This has great many advantages, one of which being that you can create seemingly infinite enumerations:
public IEnumerable<int> InfiniteOnes()
{
while (true)
yield 1;
}
Now imagine that the following:
var infiniteOnes = InfiniteOnes();
Would execute eagerly, you'd have a StackOverflow
exception coming your way quite happily.
On the other hand, because its lazy, you can do the following:
var infiniteOnes = InfiniteOnes();
//.... some code
foreach (var one in infiniteOnes.Take(100)) { ... }
And later,
foreach (var one in infiniteOnes.Take(10000)) { ... }
Iterator blocks will run only when they need to; when the enumeration is iterated, not before, not after.
Linq - What is the quickest way to find out deferred execution or not?
Generally methods that return a sequence use deferred execution:
IEnumerable<X> ---> Select ---> IEnumerable<Y>
and methods that return a single object doesn't:
IEnumerable<X> ---> First ---> Y
So, methods like Where
, Select
, Take
, Skip
, GroupBy
and OrderBy
use deferred execution because they can, while methods like First
, Single
, ToList
and ToArray
don't because they can't.
There are also two types of deferred execution. For example the Select
method will only get one item at a time when it's asked to produce an item, while the OrderBy
method will have to consume the entire source when asked to return the first item. So, if you chain an OrderBy
after a Select
, the execution will be deferred until you get the first item, but then the OrderBy
will ask the Select
for all the items.
deferred execution or not
Every statement in your question is an example of deferred execution. The contents of the Select
and Where
statement have no effect on whether or not the resulting value is deferred executed or not. The Select
+ Where
statements themselves dictate that.
As a counter example consider the Sum
method. This is always eagerly executed irrespective of what the input is.
var sum = dc.myTables.Sum(...); // Always eager
IQueryable vs. IEnumerable in the repository pattern , lazy loading
From the perspective of a Repository Pattern, you can think of it this way:
Use an eager loading
IEnumerable
when you want to pass an entire list to the client in one go. They can still add linq clauses, but the client does not benefit from deferred execution.Use a lazy loading
IQueryable
when you want to extend deferred querying capabilities to the client, by allowing the client to add their own linq clauses. This defers execution of the entire query until output is required.
See Also
Deferred execution and eager evaluation
Related Topics
Except Has Similar Effect to Distinct
How to Crop a Polygonal Area from an Image in a Winform Picturebox
Owin Security - How to Implement Oauth2 Refresh Tokens
How to Format a Nullable Datetime with Tostring()
Compare Two Lists for Differences
Compile and Run Dynamic Code, Without Generating Exe
Write Values in App.Config File
How to Make Picturebox Transparent
Filter All Queries (Trying to Achieve Soft Delete)
How to Use Httpwebrequest to Pull Image from Website to Local File
.Net Regex Matching $ with the End of the String and Not of Line, Even with Multiline Enabled
Creating PDF Files at Runtime in C#
Differencebetween a C# Reference and a Pointer
Should You Obfuscate a Commercial .Net Application
How to Resolve Service for Type While Attempting to Activate