在如何只能暴露IList<>的一个片段问题中,其中一个答案有以下代码片段:
IEnumerable<object> FilteredList()
{
foreach(object item in FullList)
{
if(IsItemInPartialList(item))
yield return item;
}
}
yield关键字在这里做什么?我在一些地方看到过它,还有一个问题,但我还没搞清楚它到底是干什么的。我习惯于从一个线程屈服于另一个线程的意义上考虑屈服,但这在这里似乎无关紧要。
关于Yield关键字的一个主要观点是惰性执行。现在我所说的惰性执行是指在需要时执行。更好的表达方式是举个例子
示例:不使用Yield,即没有Lazy Execution。
public static IEnumerable<int> CreateCollectionWithList()
{
var list = new List<int>();
list.Add(10);
list.Add(0);
list.Add(1);
list.Add(2);
list.Add(20);
return list;
}
示例:使用Yield,即惰性执行。
public static IEnumerable<int> CreateCollectionWithYield()
{
yield return 10;
for (int i = 0; i < 3; i++)
{
yield return i;
}
yield return 20;
}
当我调用两个方法时。
var listItems = CreateCollectionWithList();
var yieldedItems = CreateCollectionWithYield();
你会注意到listItems里面有5个项目(调试时将鼠标悬停在listItems上)。
而yieldItems将只有一个对方法的引用,而不是对项目的引用。
这意味着它没有在方法中执行获取项的过程。一种只在需要时获取数据的非常有效的方法。
yield的实际实现可以在ORM中看到,如Entity Framework和NHibernate等。
现在你可以在异步流中使用yield关键字。
c# 8.0引入了异步流,它对流数据源进行了建模。数据流通常异步检索或生成元素。异步流依赖于。net Standard 2.1中引入的新接口。. net Core 3.0及更高版本支持这些接口。它们为异步流数据源提供了自然的编程模型。
来源:微软文档
在下面的例子
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class Program
{
public static async Task Main()
{
List<int> numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
await foreach(int number in YieldReturnNumbers(numbers))
{
Console.WriteLine(number);
}
}
public static async IAsyncEnumerable<int> YieldReturnNumbers(List<int> numbers)
{
foreach (int number in numbers)
{
await Task.Delay(1000);
yield return number;
}
}
}
关于Yield关键字的一个主要观点是惰性执行。现在我所说的惰性执行是指在需要时执行。更好的表达方式是举个例子
示例:不使用Yield,即没有Lazy Execution。
public static IEnumerable<int> CreateCollectionWithList()
{
var list = new List<int>();
list.Add(10);
list.Add(0);
list.Add(1);
list.Add(2);
list.Add(20);
return list;
}
示例:使用Yield,即惰性执行。
public static IEnumerable<int> CreateCollectionWithYield()
{
yield return 10;
for (int i = 0; i < 3; i++)
{
yield return i;
}
yield return 20;
}
当我调用两个方法时。
var listItems = CreateCollectionWithList();
var yieldedItems = CreateCollectionWithYield();
你会注意到listItems里面有5个项目(调试时将鼠标悬停在listItems上)。
而yieldItems将只有一个对方法的引用,而不是对项目的引用。
这意味着它没有在方法中执行获取项的过程。一种只在需要时获取数据的非常有效的方法。
yield的实际实现可以在ORM中看到,如Entity Framework和NHibernate等。