Недоліки використання динамічних типів у C #


14

Я нещодавно більше вивчав динамічні типи в C #. З деякими прикладами, які я зрозумів, як тільки компілюється код, його не потрібно перекомпілювати знову, але можна виконати безпосередньо.

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

Питання,

Чи є якісь специфічні недоліки, окрім неправильних викликів динамічного методу, які викидають винятки з часу запуску, про які розробники повинні знати перед початком реалізації.


3
У C # 3 я завжди вважав використання objectчи прямого типу ролі кодовим запахом. Майже в кожному випадку це означало, що я або хтось із моєї команди не створили відповідний інтерфейс для цієї функції. Я здогадуюсь, що якби я зараз використовував C # 4, я б почувався майже так само, як і щодо використання dynamic. Я можу побачити випадок для цього, якщо ви зробите все динамічним, але в цьому випадку ви, можливо, також вибрали в першу чергу динамічну набрану мову. * 8 ')
Марк Бут

@MarkBooth +1 на перспективу. Чи можна тоді сказати, що основна реалізація за допомогою C # все ще залишатиметься сильно набраною, незважаючи на введення динамічних типів в 4.0
Karthik Sreenivasan

Використання dynamicв C # означає, що вам не доведеться відмовлятися від IronPython, якщо все, що вам потрібно, - це динамічне введення невеликої частини вашого коду. Для оцінювача виразів я мав великий успіх, використовуючи dynamicдля представлення операнди виразу та результати оцінювання.
Ед Джеймс

@EdJames - Це звучить як велика користь dynamic, плюс я хотів би, щоб я знав про IronPython, коли я розробляв .Net - це могло б зробити деякі речі, які ми намагалися зробити набагато простіше.
Марк Бут

Відповіді:


16

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

Проблема динамічного набору тексту полягає в тому, що вона часто приховує помилки, які інакше виявлялися б під час компіляції. Тоді така помилка виявляється лише під час роботи, що, звичайно, ускладнює виявлення.

ІМО дуже мало причин використовувати динамічне введення тексту на C #, головна - це співпраця з динамічно набраними мовами (що є AFAIK, тому динаміка була введена в першу чергу).

Якщо ви хочете виконати повністю динамічно набране програмування, вам слід подивитися на якусь мову, розраховану на динамічну, а не на злому C # бути динамічною. Ви можете використовувати, наприклад, IronPython, якщо ви хочете використовувати .Net бібліотеки


+1 для IronPython. Це означає, що це може призвести до проблем з технічним обслуговуванням у довгостроковій перспективі.
Karthik Sreenivasan

6
Найголовніше, що dynamicдає вам, - це можливість передати об'єкт на його фактичний тип без будь-якого виду рефлексії. Наприклад, якщо Base foo = new Derived();і було два перевантажені методи, Moo(Base x)і Moo(Derived x)тоді Moo(foo)дзвінки Moo(Base x), але Moo((dynamic)foo)дзвінки Moo(Derived x). Це призводить до дуже елегантної реалізації схеми для відвідувачів, наприклад: code.logos.com/blog/2010/03/… і, як правило, дуже потужна методика.

@TheMouthofaCow Приємно, що, звичайно, є кілька інших "законних" застосувань для динаміки, однак їх небагато і далеко між ними (і ви, безумовно, повинні знати, що ви робите, перш ніж намагатися щось подібне).
Matěj Zábský

@TheMouthofaCow Відносно новий шаблон дизайну (шаблон відвідувачів), який слід зазначити. Спасибі.
Karthik Sreenivasan

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 не мав дженериків, цей "недолік" в значній мірі не має значення.


+1 для методу розширень. Чи це стосується й інших операторів запитів LINQ, таких як GroupBy ()?
Karthik Sreenivasan

2
@Karthik: Так, це так. Я думаю, що методи розширення - це синтаксичний цукор за часом, звідси той факт, що вони не вирішуються.

@TheMouthofaCow +1 - Дякую за роз’яснення.
Картик Сріенівасан

1
Я погоджуюся з методами розширення, тобто тим, як динаміка не може з'ясувати методи розширення під час виконання, але я не міг дотримуватися динамічної колекції, яку ви пояснили.
Картик Сріенівасан

7

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

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

Тому не пишіть код динамічними типами, якщо ви не знаєте, що робите.


6

Оскільки dynamicце лише позначене, у objectньому поля значень значень.

Це може мати наслідки для продуктивності, але оскільки я все-таки використовую статичний набір тексту в критичному коді для виконання, це, мабуть, не є проблемою на практиці.

Цей бокс також заважає типам змінних значень. Якщо ви їх модифікуєте dynamic, ви змінюєте лише копію в коробці. Але оскільки ви не повинні в першу чергу використовувати типи змінних значень, це теж не є великою проблемою.


+1 Я однозначно згоден. Статичний типізація буде найкращим підходом до критичного коду щодо ефективності.
Картик Сріенівасан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.