Jam*_*ran 27
请注意,对于yield,您将迭代集合一次,但是当您构建列表时,您将迭代它两次.
以一个过滤器迭代器为例:
IEnumerator<T> Filter(this IEnumerator<T> coll, Func<T, bool> func)
{
foreach(T t in coll)
if (func(t)) yield return t;
}
Run Code Online (Sandbox Code Playgroud)
现在,你可以链接这个:
MyColl.Filter(x=> x.id > 100).Filter(x => x.val < 200).Filter (etc)
Run Code Online (Sandbox Code Playgroud)
你的方法是创建(和折腾)三个列表.我的方法只迭代一次.
此外,当您返回集合时,您正在强制对您的用户进行特定实现.迭代器更通用.
Ori*_*rds 19
我确实理解它在linq中的用处,但我觉得只有linq团队正在编写这样复杂的可查询对象,这些对象的产生是有用的.
只要它在.NET 2.0中实现,产量就很有用,早在人们想到LINQ之前很久.
我为什么要写这个函数:
IList<string> LoadStuff() {
var ret = new List<string>();
foreach(var x in SomeExternalResource)
ret.Add(x);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
当我可以使用yield时,无需充分理由就可以节省创建临时列表的工作量和复杂性:
IEnumerable<string> LoadStuff() {
foreach(var x in SomeExternalResource)
yield return x;
}
Run Code Online (Sandbox Code Playgroud)
它还具有巨大的性能优势.如果您的代码恰好使用集合的前5个元素,那么使用yield通常会避免加载超过该点的任何内容.如果您构建一个集合然后返回它,您将浪费大量的时间和空间来加载您永远不需要的东西.
我可以继续下去....
Mor*_*sen 12
我最近不得不以Expression类的形式表达数学表达式.在评估表达式时,我必须通过后序树行走来遍历树结构.为此,我实现了IEnumerable <T>,如下所示:
public IEnumerator<Expression<T>> GetEnumerator()
{
if (IsLeaf)
{
yield return this;
}
else
{
foreach (Expression<T> expr in LeftExpression)
{
yield return expr;
}
foreach (Expression<T> expr in RightExpression)
{
yield return expr;
}
yield return this;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以简单地使用foreach来遍历表达式.您还可以添加属性以根据需要更改遍历算法.
Jon*_*eet 11
在以前的公司,我发现自己写这样的循环:
for (DateTime date = schedule.StartDate; date <= schedule.EndDate;
date = date.AddDays(1))
Run Code Online (Sandbox Code Playgroud)
使用一个非常简单的迭代器块,我能够将其更改为:
foreach (DateTime date in schedule.DateRange)
Run Code Online (Sandbox Code Playgroud)
它使代码更容易阅读,IMO.
yield
是为C#2开发的(在C#3中的Linq之前).
在处理数据访问和重复计算时,我们在大型企业C#2 Web应用程序中大量使用它.
只要你有多个元素可以多次击中,集合就很棒.
然而,在许多数据访问场景中,您有大量的元素,您不一定需要在一个伟大的大集合中传递.
这基本上就是它SqlDataReader
所做的 - 它只是一个前向的自定义枚举器.
是什么yield
让你做的是快速,用最少的代码编写自定义枚举.
一切yield
都可以在C#1中完成 - 它只需要大量代码就可以完成.
Linq确实最大化了屈服行为的价值,但它肯定不是唯一的应用程序.
归档时间: |
|
查看次数: |
4488 次 |
最近记录: |