Home  >  Article  >  Backend Development  >  C# 2.0 Specification (Iterator) (1)

C# 2.0 Specification (Iterator) (1)

黄舟
黄舟Original
2017-01-03 12:00:251407browse

22Iterator

22.1 Iterator block

An iterator block is a block of statements that produces an ordered sequence of values. Iterator blocks are distinguished from regular statement blocks by one or more yield statements.
l The yield return statement produces the next value of the iteration.
l The yield break statement indicates that the iteration is complete.
The iterator block can be used as a method body (method-body), operator body (operator-body), accessor-body (accessor-body), provided that the return type of the corresponding function member is an enumerator ( enumerator) interface or one of the enumerable interfaces.
The iterator block is not a unique element in C# syntax. They are restricted in several ways, and mainly affect the semantics of function member declarations, but syntactically they are just blocks of statements.
When a function member is implemented using an iterator block, specifying any ref or out parameters for the formal parameter list will result in a compile-time error.
The return statement appearing in an iterator block will cause a compile-time error (but the yield return statement is allowed).
Including an unsafe context (§18.1) within an iterator block will result in a compile-time error. Even when the iterator declaration is embedded in an unsafe context, the iterator block is always defined as a safe context.

22.1.1 Enumerator interface

The enumerator interface (enumerator interface)[/b] is the System.Collections.IEnumerator interface and System.Collections.Generic.IEnumerator All instances. In this chapter, these interfaces will be referenced as IEnumerator and IEnumerator accordingly.

22.1.2 Enumerable interface

The enumerable interface (enumerable interface[/b])[/b] is the System.Collections.IEnumerable interface and System.Collections.Generic.IEnumerable< All instances of ;T>. In this chapter, these interfaces will be referenced as IEnumerable and IEnumerable accordingly.

22.1.3Yield type

The iterator block generates a sequence with all values ​​of the same type. The given type is called the yield[/b] type of the iterator block (yield type[/b])[/b].
l The yield type of the iterator block is usually used to implement function members that return IEnumerator or IEnumerable objects.
l The yield type of the iterator block is usually used to implement the return IEnumerator or IEnumerable which is a function member of T.

22.1.4 this access

Within an iterator block of an instance member of a class, this expression is classified as a value. The type of the value is the class type. This usage can be used in this type. The value is the reference to the object when the member is called.
In the iterator block of the instance member of the structure, this is classified as a variable when expressed. The type of the variable is the structure type in which it can be used in this way. This variable represents a copy of the corresponding structure when a member is called. Within an iterator block of a structure instance member, the this variable behaves as if it were a value parameter of the structure type.

22.2 Enumeration object

When a function member that returns an enumerator interface type is implemented using an iterator block, calling the function member will not immediately execute the code in the iterator block. Instead, an enumerator object is created and returned. This object encapsulates the code specified in the iterator block. When the enumerator object's MoveNext method is called, the code in the iterator block will be executed. Enumerator objects have the following characteristics.
l It implements IEnumerator and IEnumerator, T is the yield type (production type) of the iterator block.
l It implements System.IDisposable.



l It is initialized with a copy of the argument value (if any), and the instance value will be passed to the function member.
l It has four potential states before, running, suspended and after, and it is initialized before the before state.

The enumerator object is usually a compiler-generated enumerator class instance that encapsulates the code in the iterator statement block and implements the enumerator interface, but other implementation methods are also possible. If an enumerator class is generated by the compiler, the class will be embedded, the class will have private accessibility within the class containing the function member, and the class will have a name reserved for compiler use. (§2.4.2).
Enumerator objects can implement more interfaces than specified here.
The following sections describe the exact behavior of the MoveNext, Current, and Dispose members implemented by the IEnumerable and IEnumerable interfaces, which are provided by the enumeration object.
Please note that the enumerator object does not support the IEnumerator.Reset method. Calling this method will throw System.NotSupportedException exception.

22.2.1MoveNext method

The MoveNext method of the enumerator object encapsulates the code of the iterator block. Calling the MoveNext method will execute the code within the iterator and set the Current property of the enumeration object to the appropriate value. The precise action performed by the MoveNext method depends on the state of the enumerator object when the MoveNext method is called.
l If the enumerator object state is before, calling MoveNext
n will change the state to running.
n will initialize the parameters of the iterator block (including this) to the actual parameter values ​​and instance values ​​​​that were saved when the enumerator object was initialized.
n Execute the iterator block from the beginning until execution is interrupted (as described below).
l If the status of the enumerator object is running, the result of calling MoveNext is unspecified.
l If the status of the enumerator object is suspended, calling MoveNext
n will change the status to running.


l Restores the value of all local variables and parameters (including this) to the value of the execution state when the iterator was last suspended (suspended). Note that the contents of any object referenced by these variables may have changed since a previous call to MoveNext.
n Execution of the iterator block resumes after the yield return statement that caused execution to suspend, and this state continues until execution is interrupted (described below).
l If the status of the enumerator object is after, calling MoveNext will return false.
When MoveNext executes an iterator block, there are four ways to interrupt execution: through a yield return statement, through a yield break statement, the end point of the iterator block is reached, and an exception is thrown and propagated to outside the iterator block.
l When a yield return statement (§22.4) is encountered, the following will happen
n The expression given in the statement will be evaluated and implicitly converted to the yield type ), and is assigned to the Current property of the enumeration object.
n Execution of the iterator body will be suspended. The values ​​of all local variables and parameters (including this) are saved, as is the position of the yield return statement. If the yield return statement is within one or more try blocks, the associated finally block will not be executed at this time.
n The status of the enumerator object is changed to suspended.
n The MoveNext method returns true to the caller, indicating that the iterator successfully advanced to the next value.
l When a yield break statement is encountered, the following will occur
n If the yield break statement is within one or more try blocks, the finally statement associated with it will be executed.
n The state of the enumerator object is changed to after.
n The MoveNext method returns false to the caller, indicating that the iteration has been completed.
l When the end point of the iterator block is encountered, the following will happen.
n The state of the enumerator object is changed to after.
n The MoveNext method returns false to the caller, indicating that the iteration has been completed.


l When an exception is thrown and propagated outside the iterator block, the following will happen.
n Within the iterator block the appropriate finally block will be executed due to exception propagation.
n The state of the enumerator object is changed to after.
n For the caller of the MoveNext method, exception propagation will continue.

22.2.2 Current property

The Current property of the enumerator object is affected by the yield return statement of the iterator block.
When the enumerator object is in the suspended state, the value of Current is the value set when MoveNext was last called. When the enumerator object is in the before, running, or after state, the results of accessing Current are unspecified.
For a yield type iterator block with a non-object type, the implementation obtained by accessing Current through the IEnumerable implementation of the enumerator object corresponds to the implementation obtained by accessing Current through the IEnumerator of the enumerator object, and converting the result to object type.

22.2.3 Dispose method

The Dispose method cleans up the iteration results by setting the state of the enumerator object to after.
l If the state of the enumerator object is before, calling Dispose will change its state to after.
l If the status of the enumerator object is running, the result of calling Dispose is specified.
l If the status of the enumerator object is suspended, calling Dispose will
n change its status to running.
n Execute the finally block as if the last executed yield return statement was a yield break statement. If an exception is thrown here and propagated outside the iterator body, the enumerator object's state will be set to after, and the exception will be propagated to the caller of the Dispose method.
n Change its status to after.
l If the status of the enumerator object is after, calling Dispose has no effect.

22.3 Enumerable objects

When a function member that returns an enumerable interface type is implemented using an iterator block, calling the function member will not execute the iterator block code immediately. Instead, an enumerable object([/b]enumerable object[/b])[/b] will be created and returned. The GetEnumerator method of an enumerable object returns an enumerator object that encapsulates the code specified in the iterator block. When the MoveNext method of the enumerator object is called, the execution of the iterator block code will be triggered. Enumerable objects have the following characteristics.
l It implements the IEnumerable and IEnumerable interfaces, where T is the yield type of the iterator block.
l It is initialized with a copy of the argument value (if any) and passes the instance value to the function member.

An enumerable object is usually an instance of a compiler-generated enumerable class that encapsulates the code for an iterator block and implements the enumerable interface, but other implementation methods are also possible. If an enumerable class is generated by the compiler, the class will be embedded in the class containing the function member and have private accessibility and a name reserved for use by the compiler (§2.4.2).
Enumerable objects can implement more interfaces than explained here. In particular, an enumerable object can also implement the IEnumerator and IEnumerator interfaces, which allows it to function as both an enumerable object and an enumerator object. In that implementation type, the first call to the GetEnumerator method of an enumerable object returns the enumerable object itself. Subsequent calls to the GetEnumerator method of this enumerable object will return a copy of the enumerable object, if any. Therefore, each returned enumerator will have its own state, and changes made in one enumerator will not affect the other.

22.3.1 GetEnumerator method

The enumerable object provides an implementation of the GetEnumerator method of the IEnumerable and IEnumerable interfaces. The two GetEnumerator methods share a common implementation, which is used to get and return a valid enumerator object.
The enumerator object is initialized with the actual parameter value. When the enumerable object is initialized, its instance value will be saved. On the other hand, the enumerator object function will be as described in §22.2.
(To be continued)

The above is the content of C# 2.0 Specification (Iterator) (1). For more related content, please pay attention to the PHP Chinese website (www.php.cn)!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn