2011-01-10 3 views
33

Я планирую использовать динамическое ключевое слово для моего нового проекта. Но прежде чем войти, я хотел бы узнать о плюсах и минусах в использовании динамического ключевого слова через Reflection.Динамический Lang. Runtime vs Reflection

После где профи, я мог бы найти в отношении динамического ключевого слова:

  • читаемой \ обслуживаемой код.
  • Меньше строк кода.

Хотя негативы, связанные с использованием динамического ключевого слова, я пришел, чтобы услышать, как было:

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

Просьба помочь мне в отношении того, являются ли плюсы и минусы, с которыми я сталкивался, разумны или нет?

+0

Вам нужно сделать * частный * отражение? –

+0

Нет, мне не нужно частное отражение. То, что мне нужно, всегда нужно публиковать. – AbrahamJP

ответ

23

Читаемые \ обслуживаемой код

Конечно верно в моем ОПЫТОМ.

Меньше строк кода.

Незначительно, но это поможет.

Влияет на производительность приложения.

Очень немного.Но даже близко к тому, как отражается.

Динамическое ключевое слово внутри обертки Отражения.

Полностью не соответствует действительности. Динамическое ключевое слово использует Dynamic Library Runtime.

[Edit: коррекция в соответствии с комментарием ниже]

Казалось бы, что Dynamic Language Runtime делает использование отражения и улучшения производительности только за счет методов кэширование.

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

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

влияет на совместимость с предыдущими версиями .NET

Не верно. Я имею в виду, что вы не сможете скомпилировать свой код с более старых версий, но если вы хотите это сделать, вы должны использовать старые версии в качестве базы и перекомпилировать ее, а не наоборот. Но если вы хотите использовать библиотеку .NET 2, вам не следует запускать слишком много проблем, если вы включаете объявление в app.config/web.config.

Одним из существенных преимуществ, которые вам не хватает, является улучшенная совместимость с компонентами COM/ATL.

+0

Итак, я могу сказать, что не будет заметных различий в производительности, используя динамическое (DLR) отражение. Спасибо, что указали на улучшенную интероперабельность на COM \ ATL. – AbrahamJP

+1

@AbrahamJP - использование динамического ускорения, чем использование отражения, особенно если метод вызывается многократно (из-за кэширования). – pdr

+21

Re "Полностью не соответствует действительности. Динамическое ключевое слово использует динамическую библиотеку времени выполнения." Как вы думаете, как DLP это делает? Какую магию он имеет в своем распоряжении, благодаря чему он может выполнять анализ типа времени * без отражения?? DLR не имеет никакой магии; он использует Reflection, когда ему нужно как любой другой код. Это очень умно для кэширования результата, но поверьте мне, он использует отражение. –

4

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

Динамическое ключевое слово подрывает автоматические инструменты рефакторинга и делает более важным модульные тесты более высокого уровня; в конце концов, компилятор ничего не проверяет, когда вы его используете. Это не такая уж большая проблема, когда вы взаимодействуете с очень стабильным или по сути динамически типизированным API, но это особенно неприятно, если вы используете ключевое слово dynamic для доступа к библиотеке, API которой может измениться в будущем (например, любой код, который вы сами пишете).

Используйте ключевое слово экономно, где это имеет смысл, и убедитесь, что такой код имеет достаточные модульные тесты. Не используйте его там, где это не нужно или где вывод типа (например, var) может сделать то же самое.

Edit: Вы упоминаете ниже, что вы делаете это для плагинов. Managed Extensibility Framework был разработан с учетом этого - это может быть лучший вариант, что ключевое слово dynamic и отражение.

+1

@Eamon: Как уже упоминалось, я не использую динамическое ключевое слово для доступа к простым объектам CLR, вместо того приложения, которое я упомянул, предоставляет подключаемую модель для обработки новых функциональных возможностей, поскольку это отражение широко используется. Чтобы сделать этот модуль эффективным и поддерживаемым, меня смутило вопрос о том, нужно ли искать Reflection или ключевое слово Dynamic. Главная забота обо мне - это производительность. – AbrahamJP

+2

@AbrahamJP Поддерживается ли ваша модель плагина через интерфейсы или по соглашению? Если он поддерживается с использованием интерфейсов, то в любом случае нужно использовать небольшое отражение. Плагины –

+0

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

2

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

1

Как я вижу это все минусы для использования динамического кроме совместимости с более старыми версиями .NET также присутствуют при использовании Reflection:

влияет на производительность приложения

Хотя это влияет на производительность , так и с использованием Reflection. Из того, что я помню, DLR более или менее использует Reflection при первом доступе к методу/свойству вашего динамического объекта для заданного типа и кэширует целевую пару типа/доступа, так что более поздний доступ - это просто поиск в кеше, что делает его более быстрым затем Отражение

Динамическое ключевое слово внутренне обертка Reflection

Даже если это правда (см выше), как бы это быть отрицательным моментом? Независимо от того, делает оно или нет, отражение не должно влиять на ваше приложение в любом существенном вопросе.

Динамический ввод может превратиться в рассадник для трудно найти ошибки

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

влияет на совместимость с предыдущими версиями .NET

Для этого вы должны решить сами, сколько беспокойства это для вас.

90

Просьба помочь мне в отношении того, являются ли плюсы и минусы, с которыми я сталкивался, разумны или нет?

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

Вместо того, чтобы думать об этом с точки зрения плюсов и минусов, подумайте об этом в более нейтральных терминах. Вопрос, который я задал бы: «Каковы различия между использованием Reflection и использованием динамического типа?»

Первый: с отражением вы получаете точно то, что вы просили. С динамикой вы получите , что бы сделал компилятор C#, если бы ему была предоставлена ​​информация о типе во время компиляции. Это потенциально два полностью разные вещи. Если у вас есть MethodInfo для определенного метода и вы вызываете этот метод с определенным аргументом, то , который является вызванным методом, периодом. Если вы используете «динамический», то вы просите DLR работать во время выполнения, что мнение компилятора C# о том, что является правильным методом вызова. Компилятор C# может выбрать метод, отличный от того, который вы действительно хотели.

Во-вторых: с отражением вы можете (если ваш код предоставлен достаточно высоким уровнем доверия) делают частное отражение. Вы можете использовать частные методы, читать частные поля и т. Д. Является ли это хорошей идеей, я не знаю. Это, конечно, кажется мне опасным и глупым, но я не знаю, что такое ваша заявка. С динамикой вы получите поведение, которое вы получите от компилятора C#; частные методы и поля не отображаются.

В-третьих: с отражением код, который вы пишете, выглядит как механизм . Похоже, вы загружаете источник метаданных, извлекаете некоторые типы, извлекаете информацию о некоторых методах и вызываете методы на объектах получателя через информацию метода. Каждый шаг на пути выглядит как механизм . С динамикой каждый шаг выглядит как бизнес-логика. Вы вызываете метод на приемнике так же, как и в любом другом коде. Что важно? В некотором коде механизм на самом деле является самым важным. В некотором коде бизнес-логика, которую реализует механизм, является самой важной вещью.Выберите технику, которая подчеркивает правильный уровень абстракции.

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

+0

Спасибо за подробный анализ моего запроса. Было приятно узнать, что DLR кэширует результаты анализа. – AbrahamJP

+0

+1 приятный подробный ответ. – pqsk

+2

Это, безусловно, лучший ответ на этот вопрос –

11

Есть 4 больших отличий от Dynamic и reflection. Ниже приводится подробное объяснение того же. Ссылка http://www.codeproject.com/Articles/593881/What-is-the-difference-between-Reflection-and-Dyna

Точка 1. Осмотрите VS Invoke

Отражение может сделать две вещи один он может проверить мета-данные и второй он также имеет возможность вызывать методы runtime.While в Dynamic мы можем только вызывать методы. Поэтому, если я создаю программное обеспечение как визуальная студия IDE, тогда размышление - это путь. Если мне просто нужен динамический вызов из моего кода C#, динамический вариант - лучший вариант.

DynamicVsReflection

Пункт 2. Частный Vs Общественный Invoke

Вы не можете вызывать частные методы с использованием динамического. В отражении его можно вызвать частные методы.

Пункт 3. Кэширование

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

Пункт 4. Статические классы

Dynamic является экземпляром конкретно: У вас нет доступа к статическим членам; вы должны использовать Reflection в этих сценариях.

Смежные вопросы