Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between yield and List.AsEnumerable

Tags:

Yield is something I find tough to understand till now. But now I am getting a hold of it. Now, in a project, if I return List, Microsoft code analysis will give a warning about it. So, normally I'll do all the necessary logical parts and return the list as IEnumerable. I want to know the difference between the two. Means if I am doing yield return or otherwise.

Here is a very simple example I am showing, normally the code is a little bit complicated.

private static IEnumerable<int> getIntFromList(List<int> inputList) {     var outputlist = new List<int>();     foreach (var i in inputList)     {         if (i %2 ==0)         {             outputlist.Add(i);         }     }      return outputlist.AsEnumerable(); }  private static IEnumerable<int> getIntFromYeild(List<int> inputList) {     foreach (var i in inputList)     {         if (i%2 == 0)         {             yield return i;         }     } } 

One significant benefit I can see is fewer lines. But is there any other benefit? Should I change and update my functions which are returning IEnumearble to use yield instead of List? What is the best way or a better way to do things?

Here, I can use simple lambda expressions over List, but normally that is not the case, this example is specifically to understand best approach of coding.

like image 535
kunjee Avatar asked Jan 21 '13 07:01

kunjee


People also ask

What is the difference between List and Enumerable?

IEnumerable is a deferred execution while List is an immediate execution. IEnumerable will not execute the query until you enumerate over the data, whereas List will execute the query as soon as it's called. Deferred execution makes IEnumerable faster because it only gets the data when needed.

What is the difference between return and yield return C#?

In the iterator block, the yield keyword is used together with the return keyword to provide a value to the enumerator object. This is the value that is returned, for example, in each loop of a foreach statement. The yield keyword is also used with break to signal the end of iteration."

What is yield break in C#?

It specifies that an iterator has come to an end. You can think of yield break as a return statement which does not return a value. For example, if you define a function as an iterator, the body of the function may look like this: for (int i = 0; i < 5; i++) { yield return i; } Console.


1 Answers

Your first example is still doing all the work eagerly and building up a list in memory. In fact, the call to AsEnumerable() is pointless - you might as well use:

return outputlist; 

Your second example is lazy - it only does as much work as it needs to as the client pulls data from it.

The simplest way to show the difference is probably to put a Console.WriteLine call inside the if (i % 2 == 0) statement:

Console.WriteLine("Got a value to return: " + i); 

Then if you also put a Console.WriteLine call in the client code, e.g.

foreach (int value in getIntFromList(list)) {     Console.WriteLine("Received value: " + value); } 

... you'll see that with your first code, you see all the "Got a value" lines first, then all the "Received value" lines. With the iterator block, you'll see them interleaved.

Now imagine that your code is actually doing something expensive, and your list is very long, and the client only wants the first 3 values... with your first code, you'd be doing a load of irrelevant work. With the lazy approach, you only do as much work as you need to, in a "just in time" fashion. The second approach also doesn't need to buffer all the results up in memory - again, if the input list is very large, you'd end up with a large output list too, even if you only wanted to use a single value at a time.

like image 137
Jon Skeet Avatar answered Oct 07 '22 15:10

Jon Skeet