开发中遇到实现 IAsyncEnumerable<T>、IEnumerable<T>、IEnumerable、IEnumerator<T>、IEnumerator 接口的集合元素返回结果时我们可以使用 Yield 关键字进行迭代,Yield关键字 是遍历一个返回一个(边执行 边处理),在一些情况下会带给我们程序更好的运行效率。
yield return --用于返回集合中的元素
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(i);
yield return list[i];
}
yield break --用于中断迭代退出方法。
for (int i = 0; i < list.Count; i++)
{
if (i == 2)
yield break;
yield return list[i];
}
完整参考代码:
class YieldDemo
{
static List<string> list = new List<string>()
{
"ddd",
"eee",
"fff"
};
public static void YieldMain()
{
Console.WriteLine("---------1---------");
foreach (var item in GetList1())
{
Console.WriteLine(item);
}
Console.WriteLine("---------2---------");
foreach (var item in GetList2())
{
Console.WriteLine(item);
}
Console.WriteLine("---------3---------");
foreach (var item in GetList3())
{
Console.WriteLine(item);
}
Console.WriteLine("---------4---------");
foreach (var item in GetList4())
{
Console.WriteLine(item);
}
Console.WriteLine("---------5---------");
foreach (var item in GetList5())
{
Console.WriteLine(item);
}
Console.WriteLine("---------6---------");
foreach (var item in Power(2, 8))
{
Console.WriteLine(item);
}
}
/// <summary>
/// yield关键字返回
/// </summary>
/// <returns></returns>
private static IEnumerable<string> GetList1()
{
Console.WriteLine("1");
yield return "aaa";
Console.WriteLine("2");
yield return "bbb";
Console.WriteLine("3");
}
/// <summary>
/// 集合赋值后返回
/// </summary>
/// <returns></returns>
private static IEnumerable<string> GetList2()
{
List<string> list2 = new List<string>();
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(i);
list2.Add(list[i]);
}
return list2;
}
/// <summary>
/// 使用yield关键字返回
/// </summary>
/// <returns></returns>
private static IEnumerable<string> GetList3()
{
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(i);
yield return list[i];
}
}
/// <summary>
/// 使用yield关键字返回 yield break 中断
/// </summary>
/// <returns></returns>
private static IEnumerable<string> GetList4()
{
for (int i = 0; i < list.Count; i++)
{
if (i == 2)
yield break;
Console.WriteLine(i);
yield return list[i];
}
Console.WriteLine("yield break遍历完成");
}
/// <summary>
/// 使用yield关键字返回 break 中断
/// </summary>
/// <returns></returns>
private static IEnumerable<string> GetList5()
{
for (int i = 0; i < list.Count; i++)
{
if (i == 2)
break;
Console.WriteLine(i);
yield return list[i];
}
Console.WriteLine("break遍历完成");
}
/// <summary>
/// 微软示例
/// </summary>
/// <param name="number"></param>
/// <param name="exponent"></param>
/// <returns></returns>
public static IEnumerable<int> Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}
}
结果输出:
在第4个示例中,使用了 Yield break ,迭代中断后并没有同第5个示例 break 中断一样继续向下执行。
在第2个和第3个示例中对比了 使用 Yield return 和不使用 Yield return 的区别。