有人问过几次如何实现双向枚举器(here,here)。我的问题不是如何(对于大多数情况来说这是微不足道的),但为什么 .NET平台中不存在这样的类型。
public interface IBidirectionalEnumerator<T> : IEnumerator<T>
{
bool MovePrev();
}
显然,有许多集合类型无法实现此功能,因为MoveNext()
具有破坏性或更改底层集合的状态。但相反,许多类型可以实现这一点(List
,IList
,LinkedList
,array
)。
为什么不存在这种类型?
答案 0 :(得分:4)
当您设计框架时,您必须决定在不同的抽象级别执行操作。权衡的是,如果你选择以高抽象层次暴露事物,你将以失去对事物的细粒度控制为代价来实现泛化。如果您选择以较低的抽象级别公开内容,那么您的概念也不能一概而论,但您可以在较低级别控制细节。
这是一个设计决定。实现这两个将是昂贵的,并使框架更加膨胀,你需要在添加功能时支持两者。您将来需要保持向后兼容性。将您能想到的所有内容添加到BCL而不确定其具有显着优势并不是明智之举。
答案 1 :(得分:3)
答案 2 :(得分:2)
因为没有人想到它,或者没有人认为它会特别有用,或者因为没有足够的预算或...
这不是必要的,不是吗?您可以自己轻松实现它。也许BCL团队认为不值得实施,测试,记录等的痛苦。永远不要低估功能的成本,它可能听起来“容易”,但确实有成本。
特别是因为没有人实现的单一界面看起来很奇怪,不是吗?你会期望List,Array等实现这个接口,这最终会做很多工作。
答案 3 :(得分:2)
显然,有许多集合类型无法实现,因为
MoveNext()
具有破坏性或更改底层集合的状态。
MoveNext()
是非破坏性的。实际上,如果在创建IEnumerator
和调用时间MoveNext()
之间更改了基础集合的状态,则对MoveNext()
的调用将失败。
IEnumerator
的目的是,如果集合具有本机顺序,则按集合的本机顺序迭代集合中的所有项目。 IEnumerator
并非用作集合导航设备,例如可以在C ++中找到的设备。
答案 4 :(得分:1)
另外,这会是什么动机?语言支持“向后”迭代?
迭代器模式对一组元素的“方向性”概念没有太大影响。这是一个简单的模式,用于提供迭代集合的简单接口。
答案 5 :(得分:1)
一个更大的问题是为什么.Net不实现IReadableByIndex,而IReadableByIndex又将由IList继承。这样的类型不会增加产生读写IList实现所需的工作,并且会减少生成只读实现所需的工作(这将实现IReadableByIndex,而不是IList)。
然而,考虑这样的“为什么”并不是太有用。 .Net就是这样。解决.Net 5.0情况的唯一方法是允许一种声明实现读写属性的接口可以被认为隐式实现只读版本的方法(以便允许IList继承协变性) IReadableByIndex,无需添加显式的Get方法)。