原文:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield
When you use the yield
contextual keyword in a statement, you indicate that the method, operator, or get
accessor in which it appears is an iterator.
Using yield
to define an iterator removes the need for an explicit extra class (the class that holds the state for an enumeration, see IEnumerator<T> for an example) when you implement the IEnumerable and IEnumerator pattern for a custom collection type.
The following example shows the two forms of the yield
statement.
yield return <expression>;
yield break;
Remarks
You use a yield return
statement to return each element one at a time.
The sequence returned from an iterator method can be consumed by using a foreach statement or LINQ query. Each iteration of the foreach
loop calls the iterator method. When a yield return
statement is reached in the iterator method, expression
is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator function is called.
You can use a yield break
statement to end the iteration.
For more information about iterators, see Iterators.
Iterator methods and get accessors
The declaration of an iterator must meet the following requirements:
-
The return type must be IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>.
The yield
type of an iterator that returns IEnumerable or IEnumerator is object
. If the iterator returns IEnumerable<T> or IEnumerator<T>, there must be an implicit conversion from the type of the expression in the yield return
statement to the generic type parameter .
You can't include a yield return
or yield break
statement in:
-
Methods that contain unsafe blocks. For more information, see unsafe.
Exception handling
A yield return
statement can't be located in a try-catch block. A yield return
statement can be located in the try block of a try-finally statement.
A yield break
statement can be located in a try block or a catch block but not a finally block.
If the foreach
body (outside of the iterator method) throws an exception, a finally
block in the iterator method is executed.