目前我正在使用一些通过迭代器应用延迟执行的库。在某些情况下,我需要简单地“转发”收到的迭代器。即我必须从被调用的方法中获取IEnumerable<T>
实例并立即返回。
现在我的问题:简单地返回收到的IEnumerable<T>
或通过循环重新产生它之间是否存在相关区别?
IEnumerable<int> GetByReturn()
{
return GetIterator(); // GetIterator() returns IEnumerable<int>
}
// or:
IEnumerable<int> GetByReYielding()
{
for(var item in GetIterator()) // GetIterator() returns IEnumerable<int>
{
yield return item;
}
}
答案 0 :(得分:4)
在阅读Jon Skeet关于C#迭代器的文章时可能值得一试。这是非常有用的信息。
http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx
答案 1 :(得分:3)
他们是不同的。例如,如果GetIterator()
声明为:
IEnumerable<int> GetIterator() {
List<int> result = new List<int>();
for(int i = 0; i < 1000; i++) {
result.Add(i);
}
return result;
}
如果你没有重新屈服,GetIterator()
和循环立即执行。因此,答案取决于您如何实施GetIterator()
。如果确定GetIterator()
将会屈服,那么就没有必要重新产生它。
答案 2 :(得分:1)
除了代码膨胀之外,我没有看到任何相关的区别。
答案 3 :(得分:1)
两者之间没有任何相关的区别(除了可能表现),因为你没有对GetIterator()
的枚举器做任何事情。如果你要对枚举器做一些事情,比如过滤它就会重新产生。
答案 4 :(得分:0)
存在相关差异。
GetByReYielding()的执行将以延迟的方式执行(因为它是一个迭代器块)。如果您在GetByReturn()或GetByReYielding()中使用了一个参数并在运行时检查该参数是否为null(或进行了任何其他验证),则在调用GetByReturn()时立即执行此检查,但在调用GetByReYielding()时不立即执行此检查!当迭代结果时,GetByReYielding()中的验证将以延迟方式执行。 - 这通常是“太晚了”。见这里:
// Checks parameters early. - Fine. The passed argument will be checked directly when
// GetByReturn() is called.
IEnumerable<int> GetByReturn(IEnumerable<int> sequence)
{
if(null == sequence)
{
throw new ArgumentNullException("sequence");
}
return GetIterator();
}
// Checks parameters in a deferred manner. - Possibly not desired, it's "too" late. I.e. // when the
// result is iterated somewhere in a completely different location in your code the
// argument passed once will be checked.
IEnumerable<int> GetByReYielding(IEnumerable<int> sequence)
{
if(null == sequence)
{
throw new ArgumentNullException("sequence");
}
for(var item in GetIterator())
{
yield return item;
}
}
先生。 Skeet在http://msmvps.com/blogs/jon_skeet/archive/2010/09/03/reimplementing-linq-to-objects-part-2-quot-where-quot.aspx中解释了这个概念。 .Net中提供的标准查询运算符使用非延迟包装函数(例如Where())来检查参数,然后调用核心迭代器函数(正如我在GetByReturn()的实现中所示)。
我希望这会有所帮助。