与
有许多与 语句和迭代器方法相关的yield return
:
- CS1622:无法从迭代器中返回值。请使用 yield return 语句返回值,或生成中断以结束迭代。
- CS1624:“accessor”的正文不能为迭代器块,因为“type”不是迭代器接口类型
- CS1625:无法在 finally 子句体中生成
- CS1626:无法在包含 catch 子句的 Try 块体中生成值
- CS1627:yield return 之后应为表达式
- CS1629:迭代器中不能出现不安全的代码
- CS1631:无法在 catch 子句体中生成值
- CS1637:迭代器不能有不安全的参数或 yield 类型
- CS4013:类型的实例不能在嵌套函数、查询表达式、迭代器块或异步方法中使用
- CS8154:主体不能是迭代器块,因为它按引用返回
- CS8176:迭代器不能有按引用局部变量
- CS9238:无法在“不安全”的块中使用“yield return”
- CS9239:该
&
运算符不能用于迭代器方法中的参数或局部变量。
迭代器方法的结构
迭代器方法必须符合 C# 中的多个规则。 当你的迭代器方法违反其中一个或多个规则时,编译器会发出以下错误:
- CS1622:无法从迭代器中返回值。请使用 yield return 语句返回值,或生成中断以结束迭代。
- CS1624:“accessor”的正文不能为迭代器块,因为“type”不是迭代器接口类型
- CS1627:yield return 之后应为表达式
- CS1637:迭代器不能有不安全的参数或 yield 类型
- CS8154:主体不能是迭代器块,因为它按引用返回
你的迭代器方法必须遵循以下规则:
- 迭代器方法(使用
yield return
和可选的yield break
)也不能使用return
语句返回序列。 - 迭代器方法必须将迭代器接口类型声明为返回类型。 迭代器接口类型为:IEnumerable、IEnumerable<T>、IEnumerator、IEnumerator<T>。
yield return
语句必须包含一个表达式才能作为序列的一部分返回。yield return;
无效。- 迭代器方法不能将不安全的类型用作参数,如指针。
- 迭代器方法不能
yield return
不安全的类型,例如指针。 - 迭代器方法不能通过
yield return
ref
。 你必须按值返回。
迭代器方法的限制
迭代器方法的主体必须符合 yield return
语句及其上下文的限制。 当迭代器违反以下一个限制时,编译器会发出以下错误:
- CS1625:无法在 finally 子句体中生成
- CS1626:无法在包含 catch 子句的 Try 块体中生成值
- CS1631:无法在 catch 子句体中生成值
- CS1629:迭代器中不能出现不安全的代码
- CS9238:无法在“不安全”的块中使用“yield return”
- CS9239:该
&
运算符不能用于迭代器方法中的参数或局部变量。
这些错误表明你的代码违反了安全规则,因为迭代器返回一个元素并继续生成下一个元素:
- 你不能通过
yield return
或catch
子句执行finally
操作。 - 你不能通过 catch 子句从
yield return
执行try
操作。 - 你不能从
yield return
块中执行unsafe
操作。 迭代器的上下文在封闭的safe
块中创建嵌套的unsafe
块。 - 你不能使用
&
运算符在迭代器方法中获取变量的地址。
在 C# 13 之前,迭代器不能包含 unsafe
代码 (CS1629)。 从 C# 13 开始,此限制已放宽。 所有 yield return
语句都必须位于安全上下文中,但迭代器方法可以包含 unsafe
代码。
迭代器方法中的 ref 安全性
迭代器方法具有特殊的 ref 安全性限制。 C# 13 中放宽了这些规则:
- CS4013:类型的实例不能在嵌套函数、查询表达式、迭代器块或异步方法中使用
- CS8176:迭代器不能有按引用局部变量
在 C# 13 之前,迭代器无法声明 ref
局部变量。 它们无法声明 ref struct
类型的任何变量。
从 C# 13 开始,可以在迭代器方法中使用 ref struct
类型(如果未跨 yield return
语句访问它们)。 从 C# 13 开始,迭代器方法可以声明 ref
局部变量。