Подтвердить что ты не робот

Есть ли у ICollection <T> заказ?

Следуя правилам, которые публичные API никогда не должны возвращать список, я ослепляю преобразование всего кода, который возвратил списки, вместо ICollection<T>:

public IList<T> CommaSeparate(String value) {...}

становится

public ICollection<T> CommaSeparate(String value) {...}

И хотя ICollection имеет Count, нет способа получить элементы по этому индексу.

И хотя ICollection предоставляет перечислитель (разрешая foreach), я не вижу гарантии, что порядок перечисления начинается с "вершины" списка, а не "снизу".

я мог бы уменьшить это, избегая использования ICollection, и вместо этого используйте Collection:

public Collection<T> Commaseparate(String value) {...}

Это позволяет использовать синтаксис Items[index].

К сожалению, моя внутренняя реализация создает массив; который я может быть возвращен, чтобы вернуть IList или ICollection, но не как Collection.

Есть ли способы доступа к элементам коллекции в порядке?

Это вызывает более широкий вопрос: есть ли у ICollection порядок?


Концептуально, представить Я хочу проанализировать строку командной строки. Очень важно поддерживать порядок элементов.

Концептуально, мне нужен контракт, который указывает "упорядоченный" набор строковых кортежей. В случае контракта API для указания порядка, какое из следующего верно:

IEnumerable<String> Grob(string s)

ICollection<String> Grob(string s)

IList<String> Grob(string s)

Collection<String> Grob(string s)

List<String> Grob(string s)
4b9b3361

Ответ 1

В интерфейсе ICollection<T> ничего не указано о заказе. Объекты будут в порядке, указанном возвращенным объектом. Например, если вы возвратите коллекцию Values в SortedDictionary, объекты будут в порядке, определенном с помощью сопоставления словаря.

Если вам нужен метод для возврата по контракту типа, контракт которого требует определенного порядка, то вы должны выразить это в сигнатуре метода, возвращая более конкретный тип.

Независимо от типа времени выполнения возвращаемого объекта, рассмотрите поведение, когда статическая ссылка IList<T> или ICollection<T>: когда вы вызываете GetEnumerator() (возможно, неявно в цикле foreach), вы будете звонить тот же метод и получить тот же объект независимо от статического типа ссылки. Поэтому он будет вести себя одинаково независимо от типа возвращаемого метода CommaSeparate().

Дополнительная мысль:

Как заметил кто-то другой, правило FXCop предупреждает об использовании List<T>, а не IList<T>; связанный с вами вопрос, почему FXCop не рекомендует использовать IList<T> вместо List<T>, что является другим вопросом. Если я предполагаю, что вы разбираете строку командной строки, где порядок важен, я бы придерживался IList<T>, если бы я был вами.

Ответ 2

ICollection не имеет гарантированного порядка, но класс, который его реализует, может (или не может).

Если вы хотите вернуть упорядоченную коллекцию, верните IList<T> и не зацикливайтесь на FxCop, как правило, звук, но очень общий, совет.

Ответ 3

Экземпляр ICollection имеет "порядок" любого класса, который его реализует. То есть ссылка на List<T> как на ICollection не изменит порядок.

Аналогично, если вы получаете доступ к неупорядоченной коллекции как ICollection, она также не будет налагать порядок на неупорядоченную коллекцию.

Итак, на ваш вопрос:

Есть ли у ICollection заказ?

Ответ: он зависит исключительно от класса, который его реализует.

Ответ 4

Нет, ICollection не означает порядок.

Ответ 5

ICollection - это просто интерфейс: нет реализации или явной спецификации порядка. Это означает, что если вы возвращаете то, что перечисляется упорядоченным образом, все, что потребляет ваш ICollection, будет делать это упорядоченным образом.

Заказ подразумевается только базовым, реализующим, объектом. В ICollection нет спецификации, в которой говорится, что ее нужно заказать или нет. Перечисление по результату несколько раз вызовет базовый объект-перечислитель, который является единственным местом, где эти правила будут установлены. Объект не изменяет способ его перечисления только потому, что он наследует этот интерфейс. Если бы интерфейс указывал, что это упорядоченный результат, тогда вы можете смело полагаться на упорядоченный результат объекта-реализации.

Ответ 6

An ICollection<T> - это просто интерфейс; независимо от того, было ли оно заказано или нет, полностью зависит от реализации, лежащей в основе его (которая должна быть непрозрачной).

Если вы хотите иметь доступ к нему по индексу, вы хотите вернуть что-то в качестве IList<T>, который одновременно IEnumerable<T> и ICollection<T>. Однако следует иметь в виду, что в зависимости от базовой реализации, что получение произвольного элемента в коллекции может потребовать времени O (N/2) в среднем.

Моя склонность заключалась бы в том, чтобы полностью исключить интерфейсы коллекции и вместо этого использовать специальный тип, представляющий коллекцию в терминах проблемного домена, и подвергать соответствующие логические операции, подходящие для этого типа.

Ответ 7

ICollection<T> может иметь порядок, но фактический порядок зависит от класса, реализующего его. У него нет доступа к элементу по данному индексу. IList<T> специализируется на этом интерфейсе для обеспечения доступа по индексу.

Ответ 8

Это зависит от реализации экземпляра. ICollection, который является списком, имеет порядок, ICollection, который, случается, не является коллекцией.

Все ICollections реализуют IEnumerable, который возвращает элементы по одному, упорядочен или иным образом.

EDIT: В ответ на ваш дополнительный пример о синтаксическом анализе в вопросе, я бы сказал, что соответствующий тип возвращаемого значения зависит от того, что вы делаете с этими аргументами позже, но IEnumerable, вероятно, является правильным.

Мое рассуждение состоит в том, что IList, ICollection и их конкретные реализации допускают модификацию списка, возвращаемого из Grob, чего вы, вероятно, не хотите. Так как .NET не имеет интерфейса с индексированной последовательностью, IEnumerable - лучшая ставка, чтобы ваши вызывающие пользователи не делали что-то странное, как пытаться изменить список параметров, который они возвращают.

Ответ 9

Если вы ожидаете, что все текущие и будущие версии вашего метода не будут иметь проблемы с возвратом объекта, который сможет быстро и легко получить N-й элемент, используйте тип IList<T>, чтобы вернуть ссылку на то, что реализует оба IList<T> и не общий ICollection. Если вы ожидаете, что некоторые настоящие или будущие версии не смогут быстро и легко вернуть N-й элемент, но смогут мгновенно сообщать количество элементов, используйте тип ICollection<T>, чтобы вернуть ссылку на что-то, что реализует ICollection<T> и не общий ICollection. Если вы ожидаете, что текущие или будущие версии могут иметь проблемы, даже зная, сколько предметов есть, верните IEnumerable<T>. Вопрос о секвенировании не имеет значения; возможность доступа к N-й вещи подразумевает, что определенная последовательность существует, но ICollection<T> говорит не более и менее о последовательности, чем IEnumerable<T>.