在编程语言中,迭代器是一种可以遍历容器(如列表或数组)的元素的对象。在C#中,我们可以使用yield
关键字创建自定义的迭代器。yield
是一个强大的关键字,它使我们能够使用简洁、清晰的语法来创建和管理迭代器。
什么是Yield?
在C#中,yield
关键word用于指定一个迭代器块,也就是提供可枚举接口实现的方法。该关键字可以帮助我们更简洁地构建出返回系列值的方法。这些值可以在循环结构(如 foreach
)中使用。
Yield的使用方法
让我们通过一个例子来看看如何使用yield
:
public static IEnumerable<int> GetNumbers()
{
for (int i = 0; i < 10; i )
{
yield return i;
}
}
在上述代码中,GetNumbers
函数返回一个IEnumerable<int>
,这有助于我们在foreach循环中遍历结果:
foreach(var number in GetNumbers())
{
Console.WriteLine(number);
}
其他使用方式
除了先前提到的基础用法,yield
关键字还可以与break
配合使用来提前退出迭代。在遇到yield break
时,迭代器立即停止执行并结束迭代。
让我们看一个例子:
代码语言:javascript复制public static IEnumerable<int> GetNumbers()
{
for (int i = 0; i < 10; i )
{
if(i == 5)
yield break;
yield return i;
}
}
在上述代码中,当 i
等于 5
时,yield break
语句被执行,使得循环终止,返回的序列只包含 0, 1, 2, 3, 4
.
另外,yield
还可以用于创建无限的数据结构(虽然在实际情况中我们会通过某种方式限制迭代次数)。例如,下面这个函数可生成一个无限的整数序列:
public static IEnumerable<int> GenerateInfiniteSequence()
{
int i = 0;
while (true)
{
yield return i ;
}
}
使用如下代码可以获取前10个元素:
代码语言:javascript复制foreach(int number in GenerateInfiniteSequence().Take(10))
{
Console.WriteLine(number);
}
Yield的特性
- 延迟执行:
yield
关键字会创建一个延迟执行的迭代器。只有当你开始遍历它时,才会执行产生数据的代码。 - 状态机:
yield
关键字基本上创建了一个状态机。每次调用MoveNext()
方法时,它都会从最后一个yield return
处开始执行,直到遇到下一个yield return
。 - 内存优化:因为使用了延迟执行的特性,所以
yield
关键字在处理大数据集合时非常有用,它不需要一次性加载所有数据到内存中,只需按需加载。
注意事项
尽管yield
是一个强大的工具,但在使用它时也应注意以下几点:
- 在
yield return
语句之前不能有try-catch
块,不过可以在其内部或之后使用。 - 不能在
finally
块中使用yield return
。