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

Почему в .NET Framework отсутствует интерфейс IQueue <T> или IStack <T>?

Я хотел написать объект, работающий на подобном очереди интерфейсе. Я пошел искать IQueue<T>, но вернулся неожиданно с пустыми руками.

Существуют следующие интерфейсы, связанные с коллекцией:

  • ICollection<T>
  • IList<T>
  • IDictionary<TKey,TValue>
  • ISet<T>

Что привело к тому, что эти типы коллекций получили четко определенные интерфейсы? Почему стеки и очереди не требуют интерфейса?

4b9b3361

Ответ 1

Хорошо, потому что между этими интерфейсами можно было бы сопоставить один-на-один для классов, которые их реализуют (кроме последних ConcurrentQueue). Но другие упомянутые интерфейсы имеют множество классов, которые их реализуют.

Разверните бит. Мы не можем знать настоящую мотивацию команды BCL. Но у меня есть ощущение, что когда они создали Queue и Stack, эти классы выглядели настолько тривиальными, что они решили не абстрагировать их на интерфейсы. Причина очевидна: классы выглядели так просто, но в то же время были полными, поэтому не было причин создавать разные реализации в BCL. Затем наступил ConcurrentQueue, и предыдущее утверждение немного изменилось.

Как он указал, Queue и ConcurrentQueue не так много похожи, чтобы они реализовали единый интерфейс.

Ответ 2

Я бы предположил, что вы не видите интерфейсы Stack или Queue из-за природы коллекций. Интерфейсы коллекции, которые вы указали, которые имеют интерфейсы, представляют собой произвольный доступ, а Stacks и Queues - нет. Они должны быть доступны в особой манере (FIFO или LIFO) и поэтому не могут использоваться в целом. Поэтому имеет смысл просто использовать эти коллекции в качестве общих реализаций, но не через интерфейсы. Другими словами, из-за ограничений, которые LIFO/FIFO помещает в коллекцию, очень мало (или ничего), которые могут быть сделаны по-разному классом, который реализовал теоретический IStack или IQueue.

Чтобы реализовать эту идею, вы можете создать свой собственный IStack и/или IQueue, а затем реализовать их в классе. Вы увидите, что функциональность, которую вы открываете, будет полностью сквозной. Например. В итоге вы просто перенаправляете или возвращаете запросы и результаты во внутреннюю коллекцию Stack или Queue. И в этой сквозной функциональности будет мало или вообще ничего потенциально добавлено.

Ответ 3

Почему платформа .NET должна иметь интерфейсы IQueue<T> и IStack<T>? Что они покупают?

Что сделали эти типы коллекций получить четко определенные интерфейсы?

Библиотеки базового класса фактически используют все эти интерфейсы (IList и т.д.): в каждом случае есть группа других классов, для которых было более разумно взаимодействовать с абстракцией интерфейса, чем конкретный тип.

Почему стеки и очереди не требуют интерфейс?

Вероятно, потому что не было никаких классов BCL, которые нуждались в IStack<T> и IQueue<T>, и для этих абстракций не было очевидных или вероятных случаев использования.

Я понимаю, что это не удовлетворительный философский ответ, но похоже, что дизайнеры фреймворков были действительно прагматичны в отношении того, что получило интерфейсы: они сделали их, когда им были нужны.

Ответ 4

Я думаю, что, поскольку Stack и Queue - это очень специальные понятия, и, насколько мне известно, других классов не реализуется специальная форма стека или очереди.

EDIT:

Хорошо, теперь есть ConcurrentQueue<T>, что, похоже, отрицает мой вывод. Возможно, еще во времена, когда С# 1.0 все еще находился в стадии бета-тестирования, разработчики языка думали, что никогда не будет особой формы очереди/стека, и теперь уже слишком поздно, чтобы представить для нее интерфейс.

Это много догадок. Надеюсь, Эрик Липперт увидит этот вопрос и опубликует "официальное" выражение.: -)

Ответ 5

Я думаю, что само существование новых классов в .NET 4 ConcurrentQueue<T> и ConcurrentStack<T> доказывает вашу точку зрения, что должны быть интерфейсы IQueue<T> и IStack<T>. Даже если они не существовали первоначально, их нужно было добавить в .NET 4.

Мне пришлось создавать собственные собственные реализации Stack в прошлом в .NET и соглашаться с тем, что использование стандартного интерфейса было бы полезным.

Ответ 6

Я сомневаюсь, что была какая-то особая причина. Если бы у меня были мои druthers, было бы намного больше дискретно определенных интерфейсов, даже если бы не были классы, которые реализовали их в одиночку. Например, я мог бы реализовать QueueStack (Of T), который будет реализовывать IGetNext (Of T), IGetNextWait (Of T) и IClear (Of T), а также IQueue (Of T), IWaitQueue (Of T), IStack (Of T) и IWaitStack (Of T). Люди, потребляющие объект, могли бы точно указать, что именно они на самом деле необходимы, и исполнители должны были только реализовать то, что они утверждают, чтобы поддерживать.