Каковы различия между System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
и dynamic
?
В каких ситуациях вы используете эти типы?
Каковы различия между System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
и dynamic
?
В каких ситуациях вы используете эти типы?
dynamic
Ключевое слово используется для объявления переменных , которые должны быть поздним связыванием.
Если вы хотите использовать позднюю привязку для любого реального или воображаемого типа, используйте dynamic
ключевое слово, а остальное сделает компилятор.
Когда вы используете dynamic
ключевое слово для взаимодействия с обычным экземпляром, DLR выполняет вызовы с поздним связыванием для обычных методов экземпляра.
IDynamicMetaObjectProvider
Интерфейс позволяет классу взять под контроль его поздний связанное поведения.
Когда вы используете dynamic
ключевое слово для взаимодействия с IDynamicMetaObjectProvider
реализацией, DLR вызывает IDynamicMetaObjectProvider
методы, а сам объект решает, что делать.
ExpandoObject
И DynamicObject
классы реализации IDynamicMetaObjectProvider
.
ExpandoObject
простой класс, который позволяет вам добавлять члены к экземпляру и использовать их как dynamic
союзников.
DynamicObject
это более продвинутая реализация, которая может быть унаследована, чтобы легко обеспечить настроенное поведение.
Я постараюсь дать более четкий ответ на этот вопрос, чтобы четко объяснить, в чем различия между динамическим
ExpandoObject
иDynamicObject
.Очень быстро,
dynamic
это ключевое слово. Это не тип как таковой. Это ключевое слово, которое указывает компилятору игнорировать статическую проверку типов во время разработки и вместо этого использовать позднюю привязку во время выполнения. Таким образом, мы не собираемся тратить много времени наdynamic
остальную часть этого ответа.ExpandoObject
иDynamicObject
действительно являются типами. На поверхности они очень похожи друг на друга. Оба класса реализуютIDynamicMetaObjectProvider
. Однако, копайте глубже, и вы обнаружите, что они совсем не похожи.DynamicObject - это частичная реализация,
IDynamicMetaObjectProvider
предназначенная исключительно для того, чтобы стать отправной точкой для разработчиков для реализации своих собственных пользовательских типов, поддерживающих динамическую диспетчеризацию с настраиваемым базовым поведением хранения и извлечения для обеспечения работы динамической диспетчеризации.Короче говоря, используйте DynamicObject, когда вы хотите создать свои СОБСТВЕННЫЕ типы, которые можно использовать с DLR, и работать с любыми CUSTOM-режимами, которые вы хотите.
Пример: представьте, что вы хотите иметь динамический тип, который возвращает пользовательское значение по умолчанию при каждой попытке получить элемент, который НЕ существует (то есть не был добавлен во время выполнения). И по умолчанию будет сказано: «Извините, в этой банке нет файлов cookie!». Если вам нужен динамический объект, который ведет себя так, вам нужно контролировать, что происходит, когда поле не найдено. ExpandoObject не позволит вам сделать это. Поэтому вам нужно создать свой собственный тип с уникальным динамическим разрешением (диспетчеризацией) поведения элемента и использовать его вместо готового
ExpandoObject
.Вы можете создать тип следующим образом: (Обратите внимание, приведенный ниже код только для иллюстрации и может не работать. Чтобы узнать о том, как правильно использовать DynamicObject, в других местах есть много статей и руководств.)
Теперь мы можем использовать этот воображаемый класс, который мы только что создали, как динамический тип, который имеет очень нестандартное поведение, если поле не существует.
ExpandoObject
является полной реализациейIDynamicMetaObjectProvider
, где команда .NET Framework приняла все эти решения за вас. Это полезно, если вам не нужно никакого пользовательского поведения, и вы чувствуете, что ExpandoObject работает достаточно хорошо для вас (90% времениExpandoObject
достаточно). Так, например, смотрите следующее, и что для ExpandoObject, разработчики решили выбросить исключение, если динамический элемент не существует.Итак, подведем итог:
ExpandoObject
это просто один из заранее выбранных способов расширения DynamicObject с определенными динамическими режимами диспетчеризации, которые, вероятно, будут работать для вас , но могут не зависеть от ваших конкретных потребностей.Принимая во внимание,
DyanmicObject
что это вспомогательный BaseType, который делает реализацию ваших собственных типов с уникальным динамическим поведением простой и легкой.Полезное руководство, на котором основывается большая часть приведенного выше примера источника.
источник
DynamicObject
: при переопределенииTryGetMember
, если вы вернете false, aRuntimeBinderException
будет брошено при попытке доступа к несуществующему свойству. Чтобы фрагмент действительно работал, вы должны вернутьсяtrue
.Согласно спецификации языка C #
dynamic
это объявление типа. Т.е.dynamic x
означает, что переменнаяx
имеет типdynamic
.DynamicObject
это тип, который облегчает реализациюIDynamicMetaObjectProvider
и, таким образом, переопределяет специфическое поведение привязки для типа.ExpandoObject
это тип, который действует как мешок свойств. Т.е. вы можете добавлять свойства, методы и тому подобное к динамическим экземплярам этого типа во время выполнения.источник
dynamic
это не фактический тип ... это просто подсказка, чтобы сказать компилятору использовать позднее связывание для этой переменной.dynamic
переменные фактически объявлены какobject
в MSILПриведенный выше пример
DynamicObject
не дает четкого различия, поскольку он в основном реализует функциональность, которая уже предоставленаExpandoObject
.В двух ссылках, упомянутых ниже, очень ясно, что с помощью
DynamicObject
можно сохранить / изменить фактический тип (XElement
в примере, использованном в ссылках ниже) и лучше контролировать свойства и методы.https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/
https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject/
источник