2016-05-25 45 views
2

我正在使用对象的IReadOnlyCollection为什么IReadOnlyCollection有ElementAt但没有IndexOf

现在我有点惊讶,因为我可以使用linq扩展方法ElementAt()。但我无法访问IndexOf()

这对我来说看起来有点不合逻辑:我可以在给定的位置获取元素,但是我无法获得该元素的位置。

有没有特定的原因呢?

我已经阅读 - >How to get the index of an element in an IEnumerable?我对这个回应并不满意。

回答

2

IndexOf是在List上定义的方法,而IReadOnlyCollection只继承IEnumerable

这是因为Enumerable只是用于迭代实体。然而,指数并不适用这个概念,基本上是因为订单是任意的,并且不保证在Enumerable的调用之间相同。此外,界面只是声明,您可以迭代集合,而List指出您也可以执行添加和删除操作。

ElementOf - 方法肯定是这样。但是我不会使用它,因为它重新遍历整个枚举以找到一个单一元素。更好地使用First或只是一个基于列表的方法。

无论如何,API设计对我来说似乎很奇怪,因为它允许在第n个位置获取元素的一种(低效率)方法,但不允许获取任意元素的索引,这将导致相同的低效率多达n次迭代。我会和伊恩一起去参加(我不推荐)或者没有参加。

+2

我完全同意你这样一个事实,即枚举类型不能被索引访问,但我仍然可以使用ElementAt()。对我来说,这是一个有点傻,我得到的元素在一个给定的位置,但不是元素的位置。这更多的是一个哲学观点:) –

+1

这确实是一个奇怪的方法。我认为它的存在是因为任何人都需要这个未来,但是直到现在,对于一个'IndexOf'方法来说,并没有很高的demad。 – HimBromBeere

2

这是因为IReadOnlyCollection(实现IEnumerable)不一定实现indexing,当你想通过数字来订购List这往往需要。 IndexOf来自IList

想象一个没有索引的集合,如Dictionary例如,在Dictionary中没有数字索引的概念。在Dictionary中,顺序不能保证,键和值之间只有一对一的关系。因此,收集不一定意味着数字索引。

另一个原因是因为IEnumerable不是真正的两种方式的流量。想想这样:IEnumerable可能会列举您指定的项目x次,并找到x(即ElementAt)的元素,但它无法有效地知道它的任何元素是否位于哪个索引(即IndexOf) 。

但是,是的,它仍然是很奇怪的,即使你认为这种方式是希望它有要么ElementAtIndexOf没有。

相关问题