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