C# 迭代器 详解
这里仅针对非泛型迭代器加以说明,泛型迭代器类似。
代码一:
public class Cars
{
private int[] intArr = { 1, 2, 3, 4, 5, 6, 7 };
/// <summary>
/// 命名迭代器
/// </summary>
/// <param name="isReverse">是否倒序迭代</param>
/// <returns></returns>
public IEnumerable SortEnum(bool isReverse)
{
if (!isReverse)
{
for (int i = 0; i < intArr.Length; i++)
{
yield return intArr[i];
}
}
else
{
for (int i = intArr.Length - 1; i >= 0; i--)
{
yield return intArr[i];
}
}
}//fun
}//clas
{
private int[] intArr = { 1, 2, 3, 4, 5, 6, 7 };
/// <summary>
/// 命名迭代器
/// </summary>
/// <param name="isReverse">是否倒序迭代</param>
/// <returns></returns>
public IEnumerable SortEnum(bool isReverse)
{
if (!isReverse)
{
for (int i = 0; i < intArr.Length; i++)
{
yield return intArr[i];
}
}
else
{
for (int i = intArr.Length - 1; i >= 0; i--)
{
yield return intArr[i];
}
}
}//fun
}//clas
然后就可以对该类进行迭代操作了,代码如下:
Cars c = new Cars(); foreach (var item in c.SortEnum(true)) { Console.WriteLine(item); }
其实编译时编译器为该类生成了一个内部类,该内部类就实现了IEnumerable和IEnumerator这两个接口。
代码二:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Cars
{
public IEnumerator GetEnumerator()
{
yield return "1";
yield return "2";
yield return "3";
}//fun
}//clas
{
public IEnumerator GetEnumerator()
{
yield return "1";
yield return "2";
yield return "3";
}//fun
}//clas
示例代码如下:
//注意这里c2不用调用方法了 Cars c2 = new Cars(); foreach (var item in c2) { Console.WriteLine(item); }
编译器也为该类生成了一个内部类,该内部类实现了IEnumerator接口。
由此可见,使用yield语法,一个类型要想可以使用foreach遍历其子元素,只要满足下面两个条件之一即可:
1)有一个返回 IEnumerable 的方法,该方法内部是yield语句。
2)有一个public IEnumerator GetEnumerator() 签名的方法,内部使用yield语句。
上述代码之所以能那么写,是因为编译器帮我们实现了我们没有手动实现的条件。
作者:imap
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.