This article is a mirror article of machine translation, please click here to jump to the original article.

View: 26370|Reply: 0

[Source] C# Usage of yield keywords

[Copy link]
Posted on 5/29/2019 9:55:11 AM | | | |
1. Functions implemented by yield

yield return:

Let's take a look at the following code, which implements a function similar to traversing an array with foreach through yield return, indicating that yield return is also used to implement the function of the iterator.

yield break:

Looking at the code below, only 1 and 2 are output, but not 3, indicating that the iterator was stopped by yield break, so yield break is used to terminate iteration.

2. It can only be used in <T><T>methods, operators, get accessors that must return an IEnumerable, IEnumerable, IEnumerator, or IEnumerator.

3. The implementation principle of yield keyword

We replaced the foreach loop with a while loop and found that although we didn't implement GetEnumerator(), nor did we implement the corresponding IEnumerator's MoveNext(), and Current properties, we still worked with these functions.

As for why this is the case, we can use ILSpy to decompile the generated exe to find the reason.

Since direct decompilation to C# will become as it is



Therefore, we chose to decompile it into IL code with C# annotations, although the readability is poor, but we can understand the principles in detail.
Let's first look at the translation of the program, a new class is automatically generated during compilation.



Let's take a closer look at the code, and EnumerableFuc() returns this new class.



Looking at the implementation of the class that this code generates automatically, we can see that it inherits IEnumerable<T>, IEnumerable, IEnumerator, or IEnumerator, and we <T>should be able to guess that this new class is the reason why we don't implement the corresponding IEnumerator's MoveNext() and Current properties, but we can still use these functions normally.



Let's take a look at how this class iterates, let's mainly look at the MoveNext() function





Each call to the MoveNext() function adds 1 to the state, and a total of 4 iterations are made, the first three returning true and the last returning false, which means the end of the iteration. These four iterations correspond to the statements in enumberableFuc() that are divided into 4 parts by 3 yield return statements.

The real process of iterating with enumberableFuc() is:

1. Run the enumberableFuc() function to get an instance of the class automatically generated by the code.
2. Then call the GetEnumberator() function to start iterating on the acquired class itself as an iterator.
3. Each time you run MoveNext(), the state increases by 1, and the switch statement allows you to execute different parts of the code every time you call MoveNext().
4。 MoveNext() returns false, ending.
This also shows that the yield keyword is actually a syntactic sugar, and it is ultimately an iterative function implemented by implementing IEnumberable<T>, IEnumberable, <T>IEnumberator, and IEnumberator interfaces.





Previous:. .NET resiliency and transient failure handling Polly retry strategy
Next:HttpResult gets a set-cookie instead of a cookie
Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com