Почему в .Net такие убогие коллекции?

cdtyjv
Дата: 24.06.2014 23:55:08
Волею судеб пришлось временно перейти с Java на .Net. Пишу, значит, разный относительно _низкоуровневый_ код, и доходит дело до написания универсального обработчика коллекций. И у меня просто волосы встают дыбом от того, как имплементированы коллекции в .Net. Это просто стыд и срам.

1) ICollection не имеет метода Add. ICollection<> имеет. IDictionary<> имеет. Даже IDictionary имеет. А ICollection нет. То есть это абсолютно бессмысленный интерфейс, который не добавлять практически ничего полезного к IEnumerable. В итоге, если у меня есть в руках ICollection, я не могу добавить туда элемент. Стыд и срам.
2) Нет общей иерархии классов. ICollection<> не имеет ничего общего с ICollection. С Dictionary та же проблема. В итоге, что бы определить, что у меня в руках коллекция, нужно писать трехэтажные неэффективные выражения через рефлекшн.
3) Иерархия некоторых коллекций просто повергает в ужас. Например, ConcurrentDictionary<> имплементирует IDictionary<>, логично. Наверное, тогда и типизированный ConcurrentBag<> будет имлементировать ICollection<>, правда? Неа, он имплементирует ICollection, и какой-то совершенно идиотский типизированный producer-consumer.
4) Нет кучи полезных специализированных коллекций. Нет read-only коллекций (вернее, есть одна - для списка, а set? а dictionary?), конкаррент коллекции появились только в 4.0 и имеют отвратительнейшую иерархию, нет synchronized-оберток, как в Java. Поэтому для реализации банальнейшего сценария - выдать пользователю unmodifiable коллекцию, что бы он не наломал дров - нужно писать какие-то свои обретки. А с имеющейся иерархией попробуйте ка написать универсальную такую обертку

И весь этот сыр бор нужен только для того, что бы иметь в рантайме информацию о дженерик типе. В Джава этой информации нет, type erasure. Верите-нет, но она на практике нафиг никому не нужна. Лежат в коллекции объекты, и лежат. Зато есть простая и лаконичная иерархия классов, с которой работать - одно удовольствие. После нее от всего этого стыдобища в .Net просто глаза на лоб лезут.

Вопрос - кто проектировал это? Вам комфортно работать с коллекциями в .Net?
Изопропил
Дата: 24.06.2014 23:57:12
cdtyjv
Вам комфортно работать с коллекциями в .Net?

да. Особенно при использовании Linq For Objects
sphinx_mv
Дата: 25.06.2014 00:11:52
cdtyjv
[...бред поскипан...]
Очередное свеномное обострение...
За сим предлагаю топик закрыть.
hVostt
Дата: 25.06.2014 01:09:41
cdtyjv
1) ICollection не имеет метода Add. ICollection<> имеет. IDictionary<> имеет. Даже IDictionary имеет. А ICollection нет. То есть это абсолютно бессмысленный интерфейс, который не добавлять практически ничего полезного к IEnumerable. В итоге, если у меня есть в руках ICollection, я не могу добавить туда элемент. Стыд и срам.


свойство Count. а у IEnumerable его нет, который вообще может быть бесконечной «коллекцией».

ICollection и ICollection<T> -- разные по смыслу и замыслу интерфейсы, это совсем не тоже самое «только с типом». это и касается IDictionary/IDictionary<T>.

но детский неокрепший мозг видит одинаковые слова , и его мир начинает рушится...

cdtyjv
2) Нет общей иерархии классов. ICollection<> не имеет ничего общего с ICollection. С Dictionary та же проблема. В итоге, что бы определить, что у меня в руках коллекция, нужно писать трехэтажные неэффективные выражения через рефлекшн.


конечно, а с какого перепугу, это вдруг, должно? я не понял, зачем себя ставить в такую идиотскую ситуацию, чтобы выяснять «что за коллекция»?

cdtyjv
3) Иерархия некоторых коллекций просто повергает в ужас. Например, ConcurrentDictionary<> имплементирует IDictionary<>, логично. Наверное, тогда и типизированный ConcurrentBag<> будет имлементировать ICollection<>, правда? Неа, он имплементирует ICollection, и какой-то совершенно идиотский типизированный producer-consumer.


всё логично, если подумать тем местом, что называется голова. я же сказал ICollection и ICollection<T> никак не коррелируют друг с другом, да и были спроектированы с довольно большим интервалом времени. кое что доосмыслилось при проектировании типизированных коллекций, а старое менять нельзя, надеюсь сам понимаешь почему. очень надеюсь.

cdtyjv
4) Нет кучи полезных специализированных коллекций. Нет read-only коллекций (вернее, есть одна - для списка, а set? а dictionary?), конкаррент коллекции появились только в 4.0 и имеют отвратительнейшую иерархию, нет synchronized-оберток, как в Java. Поэтому для реализации банальнейшего сценария - выдать пользователю unmodifiable коллекцию, что бы он не наломал дров - нужно писать какие-то свои обретки. А с имеющейся иерархией попробуйте ка написать универсальную такую обертку


всё там есть. IReadOnlyDictionary, IReadOnlyCollection и IReadOnlyList.

для ISet видимо это без надобности, т.к. есть IsReadOnly на такой редкий случай.

cdtyjv
В Джава этой информации нет, type erasure. Верите-нет, но она на практике нафиг никому не нужна.


когда была жёсткая необходимость покодить на Java, я чуть не блеванул. серьёзно. хотя знаю, что имеются толпы миллионов Java-кодеров, которые вполне комфортно себя чувствуют в среде Java, но лично я после C# на Java чувствовал себя вышвырнутым за пределы нормальной цивилизации.

cdtyjv
Вопрос - кто проектировал это?


много людей, соответственно до идеала конечно далеко.

cdtyjv
Вам комфортно работать с коллекциями в .Net?


вполне.
hVostt
Дата: 25.06.2014 01:46:38
cdtyjv,

чтоб понять, почему ICollection<T> никак не может наследоваться от ICollection, рассмотрим вот такую коллекцию:

var list = new List<int> { 1, 2, 3, 4 };


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

приведём эту коллекцию к ссылке на интерфейс ICollection, который представляет собой коллекцию, хранящую какие-то Object, т.е. ссылки на объекты в куче.

стоит заморачиваться и объяснять, почему это в принципе невозможно?

с другой стороны может возникнуть вопрос, почему же тогда можно привести типизированную коллекцию к нетипизированному IEnumerable? ответ прост. потому что IEnumerable это вовсе не коллекция по сути. это интерфейс, который содержит метод, возвращающий итератор. итератор же упаковывает значение элемента и возвращает ссылку (это называется boxing, и в случае, если не применяется duck typing), или просто ссылку, если элементы коллекции являются экземплярами класса.

в Java таких заморочек нет, потому что там нет типов-значений, что позволяет .NET уделывать Java как котёнка в плане производительности.
Где-то в степи
Дата: 25.06.2014 02:13:37
hVostt,
автор
это интерфейс, который содержит метод, возвращающий итератор. итератор же упаковывает значение элемента и возвращает ссылку

в типизированых коллекциях, в случае со значениями, упаковки не проходит, там даже итератор живет живет в виде структуры.
За это, в свое время воевали наши отцы и деды.
hVostt
Дата: 25.06.2014 02:49:42
Где-то в степи
в типизированых коллекциях, в случае со значениями, упаковки не проходит, там даже итератор живет живет в виде структуры.
За это, в свое время воевали наши отцы и деды.


http://msdn.microsoft.com/ru-ru/library/system.collections.ienumerator.current.aspx
skyANA
Дата: 25.06.2014 07:57:21
hVostt
Где-то в степи
в типизированых коллекциях, в случае со значениями, упаковки не проходит, там даже итератор живет живет в виде структуры.
За это, в свое время воевали наши отцы и деды.


http://msdn.microsoft.com/ru-ru/library/system.collections.ienumerator.current.aspx
Сказать-то что хотел?
17-77
Дата: 25.06.2014 08:54:57
hVostt
когда была жёсткая необходимость покодить на Java, я чуть не блеванул

+1, я когда ставил JEE у меня постоянно сыпались ошибки в инсталяторе, каждая - гугление и исправление по полчаса-час, на пятой итерации я нажал кнопку кансел

ну ее нахрен эту яву, для линуксоидов самое то - чтоб запрограммировать хеллоу ворд - надо собрать под себя ядро
Изопропил
Дата: 25.06.2014 09:05:23
17-77
+1, я когда ставил JEE у меня постоянно сыпались ошибки в инсталяторе, каждая - гугление и исправление по полчаса-час, на пятой итерации я нажал кнопку кансел

Java то здесь причём?