bry*_*ker 22
返回可枚举时使用yield,并且此时没有所有结果.
实际上,当我想迭代大量信息(数据库,平面文件等)时,我已经使用了yield,而且我不想先将所有内容加载到内存中.Yield是一种很好的方法,可以在不加载所有内容的情况下迭代块.
该yield关键字是非常强大的.它基本上允许您快速返回IEnumerable和IEnumerator对象而无需显式编码.
考虑一种情况,您希望返回两个IEnumerable对象的交集.以下是使用yield关键字执行此操作的方法.
public static class Program
{
public static void Main()
{
IEnumerable<object> lhs = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<object> rhs = new List<int> { 3, 4, 5, 6, 7 };
foreach (object item in IntersectExample.Intersect(lhs, rhs))
{
Console.WriteLine(item);
break;
}
}
}
public static class IntersectExample
{
public static IEnumerable<object> Intersect(IEnumerable<object> lhs, IEnumerable<object> rhs)
{
var hashset = new HashSet<object>();
foreach (object item in lhs)
{
if (!hashset.Contains(item))
{
hashset.Add(item);
}
}
foreach (object item in rhs)
{
if (hashset.Contains(item))
{
yield return item;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在你完全意识到发生了什么之前,很难理解这一点.通常,当您将两个集相交时,您将完成整个操作,然后将结果返回给调用者.这意味着操作的运行时复杂性,无论您以后对结果执行什么操作O(m + n),其中m和n将是相交的集合的大小.但是,在我的例子中,我只是想从结果中挑选第一个项目.使用IEnumerable由yield关键字创建的内容,可以非常轻松地延迟部分处理,直到实际需要为止.我的例子在O(m).另一种方法是IEnumerable手动编码并维护状态.关键字的强大之yield处在于它为您创建了状态机.
该yield构造用于创建迭代器,该迭代器可以连续生成多个值:
IEnumerable<int> three_numbers() {
yield return 1;
yield return 2;
yield return 3;
}
...
foreach (var i in three_numbers()) {
// i becomes 1, 2 and 3, in turn.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2696 次 |
| 最近记录: |