Errors and warnings related to the yield return statement and iterator methods

There are numerous errors related to the yield return statement and iterator methods:

  • CS1622: Cannot return a value from an iterator. Use the yield return statement to return a value, or yield break to end the iteration.
  • CS1624: The body of 'accessor' cannot be an iterator block because 'type' is not an iterator interface type
  • CS1625: Cannot yield in the body of a finally clause
  • CS1626: Cannot yield a value in the body of a try block with a catch clause
  • CS1627: Expression expected after yield return
  • CS1629: Unsafe code may not appear in iterators
  • CS1631: Cannot yield a value in the body of a catch clause
  • CS1637: Iterators cannot have unsafe parameters or yield types
  • CS4013: Instance of type cannot be used inside a nested function, query expression, iterator block or async method
  • CS8154: The body cannot be an iterator block because it returns by reference
  • CS8176: Iterators cannot have by-reference locals
  • CS9237: 'yield return' should not be used in the body of a lock statement
  • CS9238: Cannot use 'yield return' in an 'unsafe' block
  • CS9239: The & operator cannot be used on parameters or local variables in iterator methods.

Structure of an iterator method

An iterator method must conform to several rules in C#. The compiler issues the following errors when your iterator method violates one or more of those rules:

  • CS1622: Cannot return a value from an iterator. Use the yield return statement to return a value, or yield break to end the iteration.
  • CS1624: The body of 'accessor' cannot be an iterator block because 'type' is not an iterator interface type
  • CS1627: Expression expected after yield return
  • CS1637: Iterators cannot have unsafe parameters or yield types
  • CS8154: The body cannot be an iterator block because it returns by reference

Your iterator method must follow the following rules:

  • An iterator method (using yield return and optionally yield break) can't also use a return statement to return a sequence.
  • An iterator method must declare an iterator interface type as the return type. The iterator interface types are: IEnumerable, IEnumerable<T>, IEnumerator, IEnumerator<T>.
  • A yield return statement must include an expression to return as part of a sequence. yield return; isn't valid.
  • An iterator method can't use unsafe types as parameters, such as pointers.
  • An iterator method can't yield return unsafe type, such as pointers.
  • An iterator method can't yield return by ref. You must return by value.

Restrictions on iterator methods

The body of an iterator method must conform to restrictions on the yield return statement and its context. The compiler issues the following errors when your iterator violates one of these restrictions:

  • CS1625: Cannot yield in the body of a finally clause
  • CS1626: Cannot yield a value in the body of a try block with a catch clause
  • CS1631: Cannot yield a value in the body of a catch clause
  • CS1629: Unsafe code may not appear in iterators
  • CS9237: ''yield return' should not be used in the body of a lock statement
  • CS9238: Cannot use 'yield return' in an 'unsafe' block
  • CS9239: The & operator cannot be used on parameters or local variables in iterator methods.

These errors indicate that your code violates safety rules because an iterator returns an element and resumes to generate the next element:

  • You can't yield return from a catch or finally clause.
  • You can't yield return from a try block with a catch clause.
  • You can't yield return from inside a lock statement block. Doing so can cause deadlocks.
  • You can't yield return from an unsafe block. The context for an iterator creates a nested safe block within the enclosing unsafe block.
  • You can't use the & operator to take the address of a variable in an iterator method.

Before C# 13, iterators can't contain unsafe code (CS1629). Beginning with C# 13, this restriction is relaxed. All yield return statements must be in a safe context, but an iterator method can contain unsafe code.

ref safety in iterator methods

Iterator methods have special ref safety restrictions. These rules are relaxed in C# 13:

  • CS4013: Instance of type cannot be used inside a nested function, query expression, iterator block or async method
  • CS8176: Iterators cannot have by-reference locals

Before C# 13, iterators couldn't declare ref local variables. They could not declare any variables of a ref struct type.

Beginning with C# 13, ref struct types can be used in iterator methods, if they aren't accessed across yield return statement. Beginning with C# 13, iterator methods can declare ref local variables.