10

在 SO 上已多次询问如何实现双向枚举器(此处此处)。我的问题不是如何(在大多数情况下这是微不足道的),而是为什么.NET 平台中不存在这种类型。

public interface IBidirectionalEnumerator<T> : IEnumerator<T>
{
    bool MovePrev();
}

显然,有许多集合类型无法实现这一点,因为它们MoveNext()具有破坏性或改变底层集合的状态。但相反,许多类型可以简单地实现这一点(List, IList, LinkedList, array)。

为什么不存在这种类型?

4

6 回答 6

4

当你设计一个框架时,你必须决定在不同的抽象级别上做些什么。权衡是,如果您选择在高抽象级别公开事物,您将以失去对事物的细粒度控制为代价实现泛化。如果您选择在较低抽象级别公开内容,您的概念也无法概括,但您可以在较低级别控制细节。

这是一个设计决定。实现这两者的成本很高,并且会使框架更加臃肿,并且在添加功能时需要同时支持这两者。您将来需要保持向后兼容性。将您能想到的所有内容都添加到 BCL 中而不确保它具有显着的好处,这不是明智之举。

于 2009-10-20T18:08:48.327 回答
3
  • IEnumerator 支持 c# foreach 语句以及其他语言的循环结构。
  • 没有 IbidirectionalEnumerator 启用的语句或通用编程习惯用法。
于 2009-10-20T18:07:10.490 回答
2

因为要么没有人想到它,要么没有人认为它会特别有用,或者因为没有足够的预算或......

这不是真的必要,是吗?您可以轻松地自己实现它。也许 BCL 团队认为实施、测试、记录等的痛苦是不值得的。永远不要低估一个功能的成本,这听起来“容易”,但它确实有成本。

特别是因为没有人实现的单个接口看起来很奇怪,不是吗?你会期望 List、Array 等来实现接口,这最终是相当多的工作。

于 2009-10-20T18:02:28.503 回答
2

显然,有许多集合类型无法实现这一点,因为它们MoveNext()具有破坏性或改变底层集合的状态。

MoveNext()是非破坏性的。事实上,如果底层集合的状态在IEnumerator创建和调用之间发生了变化MoveNext(),调用MoveNext()就会失败。

的目的IEnumerator是遍历集合中的所有项目一次,如果集合具有本地顺序,则按照集合的本地顺序。IEnumerator并非旨在用作集合导航设备,例如在 C++ 中可能会找到的设备。

于 2009-10-20T18:16:21.593 回答
1

另外,这样做的动机是什么?“向后”迭代的语言支持?

迭代器模式对一组元素的“方向性”概念没有给予太多重视。这是一个简单的模式,用于提供一个简单的接口来迭代一个集合。

于 2009-10-20T18:06:20.973 回答
1

一个更大的问题是为什么 .Net 没有实现 IReadableByIndex,而 IReadableByIndex 又会被 IList 继承。这种类型不会增加产生读写 IList 实现所需的工作,并且会减少产生只读实现(将实现 IReadableByIndex,而不是 IList)所需的工作。

It's not too useful to ponder such "why"s, however. .Net is what it is. The only way to remedy the situation for .Net 5.0 would be to allow a means of declaring that an interface which implements a read-write property can be deemed to implicitly implement a read-only version (so as to allow IList to inherit a covariant IReadableByIndex without having to add an explicit Get method).

于 2011-01-16T15:39:24.440 回答