2016-05-25 43 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沒有。

相關問題