Недостатки использования динамических типов в C #

14

Недавно я больше изучал динамические типы в C #. С некоторыми примерами, которые я понял после компиляции кода, его не нужно перекомпилировать снова, но можно выполнить напрямую.

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

Вопрос,

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

Картик Сринивасан
источник
3
В C # 3 я всегда считал использование objectили непосредственное приведение типов кодовым запахом. Почти в каждом случае это означало, что я или кто-то из моей команды не разработали соответствующий интерфейс для этой функции. Я предполагаю, что если бы я использовал C # 4 сейчас, я чувствовал бы то же самое и с использованием dynamicтоже. Я мог бы это доказать, если вы сделаете все динамически, но в этом случае вы могли бы также выбрать динамический типизированный язык в первую очередь. * 8 ')
Марк Бут
@MarkBooth +1 за перспективу. Тогда можно ли с уверенностью сказать, что реализация ядра с использованием C # по-прежнему будет строго типизированной, несмотря на введение динамических типов в 4.0
Картик Сринивасан,
Использование dynamicв C # означает, что вам не нужно выходить в IronPython, если все, что вам нужно, это динамическая типизация для небольшой части вашего кода. Что касается оценщика выражений, я с большим успехом использовал dynamicпредставление операндов выражения и результатов вычисления.
Эд Джеймс
@EdJames - это звучит как хорошее применение dynamic, плюс я хотел бы знать о IronPython, когда я разрабатывал с .Net - это могло бы сделать некоторые вещи, которые мы пытались сделать, намного проще.
Марк Бут

Ответы:

16

Основным недостатком является то, что вы отбрасываете одно из основных свойств (не обязательно преимуществ) C # - то, что оно статически типизировано (и для большей части типа безопасно).

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

В IMO очень мало причин использовать динамическую типизацию в C #, основной из которых является совместная работа с динамически типизированными языками (это AFAIK, причина, по которой динамический тип был введен в первую очередь).

Если вы хотите заниматься программированием с полной динамической типизацией, вам следует взглянуть на некоторый язык, который предназначен для динамического программирования, а не для взлома C # на динамический. Вы можете использовать, например, IronPython, если вы хотите использовать библиотеки .Net

Матей Забский
источник
+1 для IronPython. Это означает, что это может привести к проблемам с техническим обслуживанием в долгосрочной перспективе.
Картик Сринивасан
6
Самое важное, что dynamicдает вам - это возможность привести объект к его реальному типу без какого-либо отражения взлома. Например, если Base foo = new Derived();и было два перегруженных метода Moo(Base x)и Moo(Derived x), то Moo(foo)вызовы Moo(Base x), но Moo((dynamic)foo)вызовы Moo(Derived x). Это приводит к очень элегантной реализации шаблона Visitor, например: code.logos.com/blog/2010/03/…, и в целом является очень мощным методом.
@TheMouthofaCow Хорошо, конечно, есть и несколько других «законных» применений для динамической обработки, однако они немногочисленны и далеко друг от друга (и вы обязательно должны знать, что делаете, прежде чем пытаться что-то подобное).
Матей Забский
@TheMouthofaCow Следует отметить относительно новый шаблон дизайна (шаблон посетителя). Благодарю.
Картик Сринивасан
1
Да, это довольно круто. Я придумал это самостоятельно на прошлой неделе, поэтому было приятно видеть, что это принятая идея, которая была принята в арсенал C #.
9

Я не уверен, какие недостатки вы ищете, но если вы хотите узнать о функциях, которые работают со статической типизацией, но не с dynamic, есть несколько:

  1. Методы расширения не работают. Это, наверное, самый большой. Если у вас есть dynamic collection, вы не можете использовать код, как collection.Distinct(). Это потому, что доступные методы расширения зависят от пространства имен, usingа DLR не может их узнать.

    В качестве обходного пути, вы можете вызвать метод , как если бы это был нормальный статический метод: Enumerable.Distinct(collection). Или вы можете изменить тип коллекции на что-то вроде IEnumerable<dynamic>.

  2. foreachтребует IEnumerable. В обычном C # foreachосновывается на шаблонах. То есть, он не требует какого-либо определенного интерфейса, только GetEnumerator()метод, который возвращает подходящий объект. Если вы используете foreachна dynamic, реализации IEnumerableтребуется. Но поскольку причиной такого поведения является то, что в C # 1.0 не было обобщений, этот «недостаток» в значительной степени не имеет значения.

svick
источник
+1 за метод расширений. Относится ли это также к другим операторам запросов LINQ, таким как GroupBy ()?
Картик Сринивасан
2
@Kartik: Да, это так. Я думаю, что методы расширения являются синтаксическим сахаром времени компиляции, отсюда тот факт, что они не решаются.
@TheMouthofaCow +1 - Спасибо за разъяснения.
Картик Сринивасан
1
Я согласен с методами расширения, то есть с тем, что динамический не может определить методы расширения во время выполнения, но я не мог следить за динамическим набором, который вы объяснили.
Картик Сринивасан
7

Проблема с динамическими типами (не переменными, объявленными как динамические) в .net заключается в том, что они не обладают достаточной функциональностью, доступной статическим типам.

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

Поэтому не пишите код с динамическими типами, если вы не знаете, что делаете.

linkerro
источник
6

Так как dynamicэто просто помеченные в objectнем поля значений типов.

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

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

CodesInChaos
источник
+1 Я определенно согласен. Статическая типизация будет лучшим подходом для критичного к производительности кода.
Картик Сринивасан