yield 关键字,指示所在的方案、运算符或 get 访问器是迭代器。 使用的迭代器对集合的自定义迭代。 下面的示例演示 yield 语句的两种形式。
yield return <expression>; yield break;
使用一个 yield return 语句返回每个元素一个节点。
使用 foreach 语句或 LINQ 查询,则使用迭代器方法。 foreach 循环的每次迭代调用迭代器方法。 当 yield return 语句在迭代器方法时为止,expression 返回,并且,代码的当前位置保留。 执行从该位置下次重新启动迭代器函数调用。
可以使用 yield break 语句结束迭代。
有关迭代器的更多信息,请参见迭代器(C# 和 Visual Basic)。
迭代器方法和 get 访问器
在使用 yield return 或 yield break 语句时,则表明它的方法、运算符或 get 访问器是迭代器。 迭代器方法、运算符或 get 访问器的声明必须满足以下要求:
-
返回类型必须是 IEnumerable、IEnumerable<T>、IEnumerator或 IEnumerator<T>。
隐式转换必须从表达式的类型。yield return 语句的提供给迭代器的返回类型。
yield return 或 yield break 语句不能位于具有以下特点的方法:
-
匿名方法。 有关更多信息,请参见匿名方法(C# 编程指南)。
-
包含任何不安全的方法块。 有关更多信息,请参见unsafe(C# 参考)。
异常处理
yield return 语句不能位于 try-catch 块。 yield return 语句可以位于在尝试 try-finally 块语句。
yield break 语句可以位于 try 块或 catch finally 块,而不是块。
如果 foreach 主体 (在迭代器方法的外部) 引发异常,finally 在迭代器方法执行块。
技术实现
下面的代码从返回的迭代器方法的 IEnumerable<string> 通过其元素然后重复。
IEnumerable<string> elements = MyIteratorMethod(); foreach (string element in elements) { … }
为 MyIteratorMethod 的调用不执行方法的主体。而是调用返回 IEnumerable<string> 到 elements 变量中。
在 foreach 循环迭代中,MoveNext 方法。elements调用。这称为执行 MyIteratorMethod 主体,直至下一个 yield return 语句为止。 yield return 语句返回的表达式由循环体确定 element 变量的值不仅消耗的,而且元素 Current 属性,是 IEnumerable<string>。
在 foreach 循环的每个后续迭代中,迭代器体中执行从延续它将会停止的位置,再次停止,在到达 yield return 语句时。在迭代器方法或 yield break 语句的结尾时,foreach 循环完成。
有关更多信息,请参见 有关更多信息,请参见 C# 语言规范。该语言规范是 C# 语法和用法的权威资料。
。
下面的示例有在 for 循环内的一个 yield return 语句。 foreach 语句体的每个迭代在 Process 的创建调用 Power 迭代器函数。 每个调用迭代器函数提升到 yield return 语句的下执行,在 for 循环的下一次迭代时发生。
迭代器方法的返回类型为 IEnumerable,是迭代器接口类型。 在迭代器方法被调用时,它返回一个的幂的可枚举对象。
//using System.Collections; //using System.Diagnostics; public static void Process() { // Display powers of 2 up to the exponent of 8: foreach (int number in Power(2, 8)) { Debug.Write(number.ToString() + " "); } // Output: 2 4 8 16 32 64 128 256 } public static IEnumerable Power(int baseNumber, int highExponent) { int result = 1; for (int counter = 1; counter <= highExponent; counter++) { result = result * baseNumber; yield return result; } }
下面的示例演示是迭代器的 get 访问器。 在此示例中,每个 yield return 语句返回用户定义的选件类的实例。
public static class GalaxyClass { public static void ShowGalaxies() { var theGalaxies = new Galaxies(); foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy) { Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString()); } } public class Galaxies { public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy { get { yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 }; yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }; yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 }; yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 }; } } } public class Galaxy { public String Name { get; set; } public int MegaLightYears { get; set; } }