基本上我想知道为什么MS决定实施一个只支持前进的枚举器:MoveNext()
。
在整个.NET框架中为这个广泛使用的接口强制执行MovePrevious
是不是更灵活?
我可以想象它使Linq.Reverse
更容易为MS实现并且在性能上更有效率,但我不确定这是否会使其他事情变得更慢或者在其他所有事情上都会产生巨大的开销。
对此主题有更多了解的人可以提供更多相关信息吗?即MovePrevious
中是否有IEnumerable/IEnumerable<T>
的利弊。
答案 0 :(得分:21)
IEnumerable[<T>]
表示数据序列,而不是随机访问列表。并非所有序列都可以反转,甚至重放。基于网络流,数据库访问等的序列 - 或者这个美:
IEnumerable<int> GetData() {
Random rand = new Random();
while(true) { yield return rand.Next(); }
}
您可以做的最好的事情是重新开始 - 不,只需调用Reset()
(已弃用),而是通过获取新的枚举器。
即使没有Random
,也很容易想出不能被反转的简单序列(没有缓冲和反转缓冲区)。根据您的需要,请考虑查看IList[<T>]
- 您可以通过任何顺序通过索引器访问数据。
答案 1 :(得分:6)
有许多类型的数据,其中有一个MovePrevious是没有意义的。例如,如果您从网络连接接收数据,则提供MovePrevious将需要缓冲整个流,以防您调用该方法。这会浪费大量内存。
话虽如此,拥有一个支持MoveNext和MovePrevious的不同的类型可能会很有用(例如,双向链表可以支持此功能)。
答案 2 :(得分:1)
实施MovePrevious会使更多更重的界面。虽然对于某些来源(数组,容器类),MovePrevious将是微不足道的,对于许多其他来源,它将需要昂贵的缓冲,或排除这些来源。网络流和数据库连接不支持Seek操作。
答案 3 :(得分:1)
在设计界面时,使用方便不是唯一的因素...你必须考虑它的多样性以及你将如何添加约束。
有些序列无法重播,你会为实现它添加许多不必要的要求。
除此之外还有其他接口,如IList,IQueryable。使用最适合该场景的,还可以传达它应该具有的使用类型。
答案 4 :(得分:0)
这与“收益率”的模式有关。有效的调查员是最简单的集合,你只需从前面开始直到最后。这意味着他们编写实现枚举的代码非常简单。
此外,您可以使用永远不会“结束”的迭代器来使用功能代码,例如
yield value++;
在您停止之前,您只会收到递增的数字。