Динамический Ланг.Время выполнения против отражения - PullRequest
37 голосов
/ 10 января 2011

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

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

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

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

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

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

Ответы [ 6 ]

98 голосов
/ 10 января 2011

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

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

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

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

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

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

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

25 голосов
/ 10 января 2011

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

Конечно, верно в моем опыте.

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

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

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

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

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

Совершенно неверно.Ключевое слово dynamic использует динамическую библиотечную среду выполнения.

[Редактировать: исправление в соответствии с комментарием ниже]

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

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

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

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

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

Один важный профессионал, который вы 'Отсутствует улучшенная совместимость с компонентами COM / ATL.

12 голосов
/ 22 мая 2013

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

Точка 1. Проверьте VS Invoke

Отражение может делать две вещи: во-первых, оно может проверять метаданные, а во-вторых, оно также может вызывать методы во время выполнения. В Dynamic мы можем вызывать только методы. Так что, если я создаю программное обеспечение, как Visual Studio IDE, то рефлексия - это путь. Если я просто хочу динамический вызов из моего кода на c #, динамический - лучший вариант.

DynamicVsReflection

Пункт 2. Частный и публичный вызов

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

Точка 3. Кэширование

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

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

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

4 голосов
/ 10 января 2011

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

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

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

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

2 голосов
/ 10 января 2011

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

1 голос
/ 10 января 2011

То, как я вижу все ваши недостатки использования динамического, за исключением возможности взаимодействия со старыми версиями .NET, также присутствует при использовании Reflection:

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

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

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

Даже если бы это было правдой (см. Выше), как бы это было отрицательным моментом? Обертка Reflection не влияет на ваше приложение в каких-либо существенных вопросах.

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

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

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

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

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