путаница C # утка, типизация, неявное преобразование и несоответствия - PullRequest
1 голос
/ 03 июня 2009

Всем нравится печатать на утке, если она выглядит как утка, ведет себя как утка, относится к ней как к утке. C # 4.0 позволяет вводить утку, и текущая поддерживает ее в нескольких ситуациях (см. «C # уже давно использовал набор утки» в http://www.eioba.com/a75370/how_duck_typing_benefits_c_developers)

Теперь ... почти все имеют .AnotherType (). Я не могу понять, что int требует .ToString (), но нужен ли списку действительно .ToArray () при передаче его в функцию, которая требует obj []? Это кажется противоречивым.

Может ли кто-нибудь объяснить несоответствия, объяснить случаи, почему .ToArray имеет смысл (или любые другие дизайнерские решения), или дать мне какой-либо тип понимания?

Ответы [ 2 ]

7 голосов
/ 03 июня 2009

Практически любая коллекция должна предоставлять средства, позволяющие создавать ее из других общих коллекций или разрешать превращать ее (или даже лучше обрабатывать, как) в другие общие коллекции.

Массивы являются мощными, но сложными для размышления, так как они (по своей природе) изменчивы, но это позволяет проводить некоторые мощные оптимизации там, где это необходимо (например, эффективные реализации быстрой сортировки действительно должны иметь возможность менять элементы на месте).
Последовательности (IEnumerable<T> для вас) превосходны, поскольку они так мало требуют самих себя (включая критически важный способ их изменения), что означает, что код, ожидающий их, имеет тенденцию быть очень гибким и широко полезным.

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

Уже существует множество API-интерфейсов, которые ожидают сбора определенного типа, возможные причины:

  • Написано до изменений 2.0, которые сделали коллекции намного богаче в .Net
  • Поскольку они знают, что им нужно изменить состояние, они заставляют звонящего отвечать за предоставление состояние, которое будет изменено (например, функции сортировки по месту)
  • Они были написаны плохо

Стоит отметить, что отсутствие какой-либо строго типизированной коллекции в .Net pre 2.0, кроме массивов, означает, что многие API-интерфейсы BCL, задним числом, плохо разработаны. API отражения в BCL являются примечательными примерами, возвращающими массивы повсеместно, когда они должны быть IEnumerable.

Таким образом, возможность простого перехода из одного вида явного набора в другой очень полезна в реальном мире.

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

Ответ на этот вопрос - это зависит (и динамика действительно что-то меняет, но не сильно).

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

Где все становится сложным, там, где функции требуют конкретных типов. Опять же, плохой предварительный дизайн, такой как отсутствие интерфейса ISet при добавлении HashSet, означает, что если у вас есть метод, который действительно нуждается в наборе, вы вынуждены перейти к конкретному типу или свернуть свой собственный ISet и поддержку Set - не очень приятно. Определенные операции преобразования, скажем, из набора в список, осуществимы в контексте только для чтения (вы просто детерминистически перечислите все значения в наборе), но не в контексте записи (вы можете добавить что-то в список дважды, но не набор, например)

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

Dynamic делает вещи несколько сложными, так как для сохранения (грубо говоря) «аксиомы» его реализации, что при использовании динамического вы должны получить тот же результат, как если бы присутствовала статическая типизация, он должен иметь дело со случаями, такими как волшебство времени выполнения на массивы.

0 голосов
/ 03 июня 2009

Я думаю, что инфраструктура коллекций Java намного превосходит .net one ...

Например ... в Linq, когда вы выполняете и .orderBy, вы не можете вернуть его как коллекцию ....

Все должно наследоваться от iCollection ......

Я надеюсь, что в версии 4 * 1007 фреймворк коллекции будет очень похож на Java

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...