yield(C# 参考)
在语句中使用 yield 关键字,则指示在的方案、运算符或 get 访问器是迭代器。使用的迭代器对集合的自定义迭代。下面的示例演示 yield 语句的两种形式。
yield return <expression>;
yield break;
备注
使用一个 yield return 语句返回每个元素一个节点。
使用 foreach 语句或 LINQ 查询,则使用迭代器方法。foreach 循环的每次迭代调用迭代器方法。当 yield return 语句在迭代器方法时为止,expression 返回,并且,代码的当前位置保留。执行从该位置下次重新启动迭代器函数调用。
可以使用 yield break 语句结束迭代。
有关迭代器的更多信息,请参见迭代器(C# 和 Visual Basic)。
迭代器方法和 get 访问器
迭代器的声明必须满足以下要求:
返回类型必须是 IEnumerable、IEnumerable<T>、IEnumerator或 IEnumerator<T>。
该声明不能有任何 ref 或 t3c3bfhx(v=vs.110).md 参数。
隐式转换必须从表达式的类型。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 循环完成。
示例
下面的示例有在 for 循环内的一个 yield return 语句。foreach 语句体的每个迭代在 Process 的创建调用 Power 迭代器函数。每个调用迭代器函数提升到 yield return 语句的下执行,在 for 循环的下一次迭代时发生。
迭代器方法的返回类型为 IEnumerable,是迭代器接口类型。在迭代器方法被调用时,它返回一个的幂的可枚举对象。
public class PowersOf2
{
static void Main()
{
// Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}
public static System.Collections.IEnumerable Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}
// Output: 2 4 8 16 32 64 128 256
}
下面的示例演示是迭代器的 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; }
}
}
C# 语言规范
有关更多信息,请参见 C# 语言规范。该语言规范是 C# 语法和用法的权威资料。