What Is the Yield Keyword Used For in C#

What is the yield keyword used for in C#?

The yield contextual keyword actually does quite a lot here.

The function returns an object that implements the IEnumerable<object> interface. If a calling function starts foreaching over this object, the function is called again until it "yields". This is syntactic sugar introduced in C# 2.0. In earlier versions you had to create your own IEnumerable and IEnumerator objects to do stuff like this.

The easiest way understand code like this is to type-in an example, set some breakpoints and see what happens. Try stepping through this example:

public void Consumer()
{
foreach(int i in Integers())
{
Console.WriteLine(i.ToString());
}
}

public IEnumerable<int> Integers()
{
yield return 1;
yield return 2;
yield return 4;
yield return 8;
yield return 16;
yield return 16777216;
}

When you step through the example, you'll find the first call to Integers() returns 1. The second call returns 2 and the line yield return 1 is not executed again.

Here is a real-life example:

public IEnumerable<T> Read<T>(string sql, Func<IDataReader, T> make, params object[] parms)
{
using (var connection = CreateConnection())
{
using (var command = CreateCommand(CommandType.Text, sql, connection, parms))
{
command.CommandTimeout = dataBaseSettings.ReadCommandTimeout;
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return make(reader);
}
}
}
}
}

Explaining yield keyword in C#

What MSDN days :

The yield keyword signals to the compiler that the method in which it
appears is an iterator block. The compiler generates a class to
implement the behavior that is expressed in the iterator block. 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.


In simple word :

yield return return a Collection of Object instead of returning a single object

    static void Main(string[] args)
{

int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// supposed u need to find all the numbers which are greater then 5
// in general it could have been done like

foreach (int number in numbers)
{
if (number > 5)
{
Console.WriteLine(number);
}

}

// what if u needed the numbers that are greater then 5 multiple times, each time you would have to start a loop
// yield return helps to return a collection of int
var needed_numbers = NeededNumbers(numbers);

foreach (int neededNumber in needed_numbers)
{
Console.WriteLine(neededNumber);
}
}

private static IEnumerable<int> NeededNumbers(int[] nums)
{
foreach (int number in nums)
{
if (number > 5)
{
yield return number;
}

}
}

Quote from DotNetPerls

The yield return statement is semantically equivalent to a return
statement (which passes control flow to the calling method), followed
by a "goto" to the yield statement in the next iteration of the
foreach loop.

Why use the yield keyword, when I could just use an ordinary IEnumerable?

Using yield makes the collection lazy.

Let's say you just need the first five items. Your way, I have to loop through the entire list to get the first five items. With yield, I only loop through the first five items.

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.

What is yield and what is the benefit to use yield in asp .NET?

Yield return automatically creates an enumerator for you.

http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx

So you can do something like

//pseudo code:

while(get_next_record_from_database)
{
yield return your_next_record;
}

It allows you to quickly create an object collection (an Enumerator) that you can loop through and retrieve records. The yield return statement handles all the of the code needed to create an enumerator for you.

The big part of the yield return statement is that you don't have to load all the of the items in a collection before returning the collection to the calling method. It allows lazy loading of the collection, so you don't pay the access penalty all at once.

When to use Yield Return.

Is 'yield' keyword a syntactic sugar ? What is its Implementation

The generated code depends on the original, but generally speaking a state machine gets generated which keeps track of the current state of the collection.

See yield statement implementation, this answer by Eric Lippert and this blog post by Jon Skeet.

Proper use of 'yield return'

I tend to use yield-return when I calculate the next item in the list (or even the next group of items).

Using your Version 2, you must have the complete list before returning.
By using yield-return, you really only need to have the next item before returning.

Among other things, this helps spread the computational cost of complex calculations over a larger time-frame. For example, if the list is hooked up to a GUI and the user never goes to the last page, you never calculate the final items in the list.

Another case where yield-return is preferable is if the IEnumerable represents an infinite set. Consider the list of Prime Numbers, or an infinite list of random numbers. You can never return the full IEnumerable at once, so you use yield-return to return the list incrementally.

In your particular example, you have the full list of products, so I'd use Version 2.



Related Topics



Leave a reply



Submit