Как стать автором
Обновить

Комментарии 13

Угу, и добавить IStack и IQueue… и аккуратно вписать в иерархию INotifyCollectionChanged…
Не понимаю, кто мешает это сделать сейчас. Ввели же обобщенные интерфейсы. Ну так введите еще одно пространство имен с новыми, более логичными интерфейсами. И их иерархию лучше подсмотреть у джавы, а то в .NET-е такие чудеса порой. Пока единственная нелогичность в джаве с итераторами — у итератора есть метод remove(), который может кидать исключение, если итератор read-only, но почему-то нет аналогичного метода add() и set().

Кстати, насчет обобщенных обобщенных интерфейсов — не понимаю, зачем Майкрософт ввел новые интерфейсы, а не переделал уже существующие — все равно официальная реализация языка была только одна от них же — предоставили бы утилиту для конвертации байткода и всего делов. Да даже и утилита не нужна, CLR сама все могла сделать. Нет, зачем-то развезли кашу.
Видимо, проще наплодить еще интерфейсов, чем изменять CLR. Эрик очень любит на любой фичреквест бегать, обхватив голову руками, и кричать «да вы представляете, СКОЛЬКО кода нужно, чтобы реализовать эту вашу финтифлюшку?.. Так что нафиг её». Собственно, rosylin имхо для этого и делают, чтобы можно было легко и непринужденно вносить изменения в язык, задумываясь не об их сложности, а об их необходимости.
Слово «фундамент» поправьте, пожалуйста…
Поправил, спасибо
Принцип Лисков как священное писание как только его не трактуют :)
Не согласен с вашей архитектурой. У вас получается, что массив наследует IList со всеми текущими проблемами. Ради интереса
            int[] arr = {1, 2, 3};
            var methods = typeof(IList<int>).GetMethods().Concat(typeof(IList).GetMethods());
            int success = 0, failed = 0;
            foreach (var methodInfo in methods)
            {
                try
                {
                    var paramss = methodInfo.GetParameters().Select(x => x.DefaultValue).ToArray();
                    methodInfo.Invoke(arr, paramss);
                    Console.WriteLine("{0} successed", methodInfo.Name);
                    success++;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("{0} failed for reason {1}", methodInfo.Name, ex.GetType().Name);
                    failed++;
                }
            }
            Console.WriteLine("Success = {0}\tFailed={1}", success, failed);

удачно выполняется 5 методов, а 11 падает с исключением. О чем может идти речь, большая часть методов от IList в массиве бросает исключения?..

Мне намного больше нравится идея парня со stackoverflow
IMO there should be several more (generic) collection interfaces depending on the features of a collection. And the names should have been different too, List for something with an indexer is really stupid IMO.

  • Just Enumeration IEnumerable&ltT>
  • Readonly but no indexer (.Count, .Contains,...)
  • Resizable but no indexer, i.e. set like (Add, Remove,...) current ICollection&ltT>
  • Readonly with indexer (indexer, indexof,...)
  • Constant size with indexer (indexer with a setter)
  • Variable size with indexer (Insert,...) current IList&ltT>


I think the current collection interfaces are bad design. But since they have properties telling you which methods are valid(and this is part of the contract of these methods) it doesn't break the substitution principle.
А, неправильно прочитал диаграмму. Так да, намного более логичная иерархия. Но всё равно имхо перегружено. Когда я хочу простенький индексатор в свою коллекцию, мне приходится переопределять миллиард всевозможных методов, это же просто беда какая-то. Почему бы не разделить эти интерфейсы, а для совокупности их сделать общий интерфейс? К примеру IFixedList&ltT>: IReadOnlyList&ltT>, IIndexable&ltT>, с убиранием из IReadOnlyList индексатора соответственно.
В моём понимании это как-то так должно выглядеть:
image

Хотя в любом случае, даже приведенный выше дизайн много лучше того, что сейчас наворотили во фреймворке. Жалко, что груз обратной совместимости не дает исправить это…
Идея кардинально разделить интерфейсы интересная, но мне кажется тут как минимум нужно чтобы все они наследовали от IEnumerable<T>, иначе перестанет работать LINQ.
Да, конечно, это просто зарисовка, тут много чего нужно исправлять. Конечно, IEnumerable&ltT> должен быть самым общим интерфейсом.

Просто очень печально, когда я хочу сделать биективный словарь (то есть для каждого x,y, если dict[x] = y, то dict[y] = x), то мне нужно либо переопределить миллиард методов IDictionary<T,T>, либо наследовать обычный Dictionary, и определять новый Add, но не переопределять!, поэтому при вызове по ссылке базового класса всё посыпется.

Хотелось бы как-то побольше гибкости.
То что вы нарисовали — Иерархия коллекций Scala. Правда упрощенная.
Советую обратить внимание туда, ИМХО на данный момент это самые близкие к полнофункциональным коллекции.
Действительно, загуглил — отличная архитектура. Спасибо за информацию
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории