Need help understanding C # exit in IEnumerable

I am reading C # 2010 Accelerated. I do not understand what yield

When GetEnumerator is called, the code in the method that contains the yield does not actually execute at that point in time. Instead, the compiler generates a class enumerator, and this class contains the output code block.

 public IEnumerator<T> GetEnumerator() { foreach( T item in items ) { yield return item; } } 

I also read from Some help to understand the "way out"

income is a lazy data producer, only the creation of another item after the first has been restored, and the return list will return all in one go.

Does this mean that every call to GetEnumerator will get 1 item from the collection? so the 1st call I get the 1st item, the 2nd, I get the 2nd and so on ...?

+4
source share
6 answers

The best way to think about this is when you first request an element from IEnumerator (for example, in foreach ), it is launched through a method, and when it falls into yield return , it pauses execution and returns that element for use in foreach . Then you request the next element, it resumes the code in which it is located, and repeats the loop until it encounters either yield break or the end of the method.

 public IEnumerator<string> enumerateSomeStrings() { yield return "one"; yield return "two"; var array = new[] { "three", "four" } foreach (var item in array) yield return item; yield return "five"; } 
+6
source

Take a look at the IEnumerator<T> interface; which may well clarify what is happening. The compiler takes your code and turns it into a class that implements both IEnumerable<T> and IEnumerator<T> . The call to GetEnumerator () simply returns the class itself.

The implementation is basically a state machine, which for each call to MoveNext () executes the code until the next yield return , and then sets Current to the return value. The foreach uses this enumerator to move through the listed items, calling MoveNext () before each iteration of the loop. The compiler really does very interesting things here, creating yield return one of the most powerful constructs in this language. From a programmer’s point of view, this is an easy way to lazily return items upon request.

+2
source

Yes, that's right, here is an example from MSDN that illustrates how to use it

 public class List { //using System.Collections; public static IEnumerable Power(int number, int exponent) { int counter = 0; int result = 1; while (counter++ < exponent) { result = result * number; yield return result; } } static void Main() { // Display powers of 2 up to the exponent 8: foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); } } } /* Output: 2 4 8 16 32 64 128 256 */ 
+1
source

If I understand your question correctly, your understanding is incorrect. I'm afraid. Profitability operators (profitability and profitability) are a very smart compiler trick. The code in your method is actually compiled into a class that implements IEnumerable. An instance of this class returns a method. Let us call an instance of "ins" when calling ins.GetEnumerator (), you get an IEnumerator that for each call to MoveNext () created the next element in the collection (return income is responsible for this part) when the sequence has no more elements (for example, there is a gap exit) MoveNext () returns false, and further calls throw an exception. So this is not a call to GetEnumerator that created the (next) element, but Call to MoveNext

+1
source

You seem to understand that.

yield used in your GetEnumerator class, as you describe, so you can write code like this:

 foreach (MyObject myObject in myObjectCollection) { // Do something with myObject } 

Having returned the first element from the first call, the second from the second, etc., you can iterate over all the elements in the collection.

yield defined in MyObjectCollection .

0
source

An easy way to understand the yield keyword is that we don’t need an extra class to store the iteration result when returning using return return. Usually, when we iterate over a collection and want to return the result, we use the collection object to save the result. Consider an example.

public static Multiplication List (int number, int times)

  { List<int> resultList = new List<int>(); int result = number; for(int i=1;i<=times;i++) { result=number*i; resultList.Add(result); } return resultList; } 

static void Main (string [] args)

  { foreach(int i in Multiplication(2,10)) { Console.WriteLine(i); } Console.ReadKey(); } 

In the above example, I want to return the result of multiplication by 2 times. Therefore, I create a multiplication method that returns me a multiplication of 2 ten times, and I save the result in the list, and when my main method calls the multiplication, the control is repeated ten times through the loop and the result of the result in the list. This is without using a return return. Suppose that if I want to do this with a return on profitability, it looks like

public static IEnumerable Multiplication (int number, int times)

  { int result = number; for(int i=1;i<=times;i++) { result=number*i; yield return result; } } 

static void Main (string [] args)

  { foreach(int i in Multiplication(2,10)) { Console.WriteLine(i); } Console.ReadKey(); } 

Now there are small changes in the multiplication method, the return type is IEnumerable, and there is no other storage list because to work with the return type, the return value must be IEnumerable or IEnumerator, and since Yield provides stateful iteration, we don’t need an additional storage class result. So, in the above example, when the multiplication method is called from the Main method, it calculates the result for the 1st iteration and returns the result to the main method and returns to the loop and calculate the result for the 2nd iteration and return the result to the main method. Thus, the return returns to the method call one by one in each iteration. There is another keyword gap used in conjunction with Yield that causes the iteration to stop. For example, in the above example, if I want to calculate the multiplication only half the number of times (10/2 = 5), then the method looks like this:

public static IEnumerable Multiplication (int number, int times)

  { int result = number; for(int i=1;i<=times;i++) { result=number*i; yield return result; if (i == times / 2) yield break; } } 

This method will now lead to multiplication in 2, 5 times. Hope this helps you understand the concept of profitability. For more, please visit http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx

0
source

All Articles