我几乎不使用“yield”运算符(我不讨厌它:))。如果有可能,我更喜欢使用LINQ。 无论如何,我找了一些帖子(你可以在下面找到链接)10分钟前,阅读它和一些想法访问了我的大脑:)
rewrite-this-foreach-yield-to-a-linq-yield
想法:可能,我不使用“收益率”并不是很好。可能它具有比LINQ更好的性能或其他一些优势。
因此我有下一个问题,上面的例子(通常情况下)中哪些代码更“正确”(yield或LINQ)?
P.S。当我们有可能使用LINQ而不是“yield”时,我感兴趣。
答案 0 :(得分:8)
在个人情况下,我认为在这种情况下使用LINQ是更清楚。它的操作级别高于“调用此方法,产生此结果” - 它描述整体结果。
Iterator块对实现 LINQ非常有用 - 无论是现有的运算符,还是添加自己的运算符。值得知道关于它们,但我不担心你没有太多使用它们 - 这不是代码不好的标志或类似的东西。
答案 1 :(得分:2)
public static IEnumerable<Color> GetThemColors(){
GetThePrimaryIds().Select(id=>yield return GetColorById(id));
GetTheOtherIds().Select(id=>yield return GetOtherColorsById(id));
}
此代码不起作用。 Select是惰性的,不会枚举这些集合。
答案 2 :(得分:1)
暂时忽略Linq可由其他查询提供程序处理的方式(例如,针对数据库),在您链接到的示例中,我们有两种不同的方法:
Enumerable.Concat
方法。嗯,Enumerable.Concat
是什么?由于我们忽略了像Linq2SQL这样的情况(可能会将concat变成UNION ALL
),我们在这里关心的是Linq2Objects实现。
现在,有一种方法来设置连接,但是Mono源(例如)最终会调用一个支票然后进入:
static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
{
foreach (TSource element in first)
yield return element;
foreach (TSource element in second)
yield return element;
}
换句话说,LINQ方法是 yield
方法。
如果不是,它可能是非常相似的东西。我们可以(如果我们喜欢输入更多内容)将其实现为构建IEnumerator<TSource>
的实现,但yield
为我们省去了麻烦。
总而言之,LINQ是一系列可以很好地协同工作的便捷工具。如果它们是运行良好的工具,请使用它们。当其他工具更好用时,请使用它。当一个类似LINQ的工具会很好,但它没有包含在你所拥有的内容中时,请自己编写(就像我们可以在Linq之前完成所有Linq2Objects的东西,这在.NET2.0中不适用于我们)