2016-05-25 12 views
2

Я работаю с объектами IReadOnlyCollection.Почему у IReadOnlyCollection есть ElementAt, но не IndexOf

Теперь я немного удивлен, потому что я могу использовать метод расширения linqElementAt(). Но у меня нет доступа к IndexOf().

Это выглядит немного нелогично: я могу получить элемент в заданном положении, но я не могу получить позицию этого самого элемента.

Есть ли для этого конкретная причина?

Я уже читал ->How to get the index of an element in an IEnumerable?, и я не совсем доволен ответом.

ответ

2

IndexOf - метод, определенный по List, тогда как IReadOnlyCollection наследует только IEnumerable.

Это потому, что Enumerable ist просто для итерации объектов. Однако индекс не применяет эту концепцию, в основном потому, что порядок произволен и не гарантируется быть идентичным между вызовами Enumerable. Кроме того, интерфейс просто заявляет, что вы можете перечислить коллекцию, тогда как List заявляет, что вы можете выполнять добавление и удаление.

ElementOf-метод точно делает именно это. Однако я не буду использовать его, поскольку он повторяет все перечисление, чтобы найти один элемент. Лучше использовать First или просто подход на основе списка.

В любом случае API-дизайн кажется мне странным, поскольку он позволяет (неэффективно) подходить к получению элемента на n-й позиции, но не позволяет получить индекс произвольного элемента, который был бы таким же неэффективным, что до n итераций. Я поеду с Иэном на обоих обоих (что я не буду рекомендовать) или нет.

+2

Я полностью согласен с вами в том, что Enumerables не предназначен для доступа по индексу, но все же я могу использовать ElementAt(). Для меня это немного глупо, я получаю элемент в заданной позиции, но не позицию элемента.Это скорее философский момент :) –

+1

Это действительно странный метод. Я предполагаю, что это просто существует, потому что кому-то понадобилось это будущее, однако до сих пор не было высокого уровня в отношении метода IndexOf. – HimBromBeere

2

Это происходит потому, что IReadOnlyCollection (который реализует IEnumerable) не обязательно осуществлять indexing, которая часто требуется, если вы хотите, чтобы численно заказать List. IndexOf от IList.

Подумайте о коллекции без индекса, например Dictionary, нет понятия числового индекса в Dictionary. В Dictionary заказ не гарантируется, только один к одному отношение между ключом и значением. Таким образом, сбор не обязательно подразумевает числовое индексирование.

Другая причина в том, что IEnumerable на самом деле не является двумя способами движения. Подумайте об этом так: IEnumerable может перечислять элементы x раз, как вы указали, и найти элемент на x (то есть ElementAt), но он не может эффективно знать, находится ли какой-либо его элемент, в каком индексе (то есть IndexOf) ,

Но да, это все еще довольно странно, даже вы думаете, это так, как и следовало ожидать, что иметь либо как ElementAt и IndexOfили никто.