С# 4: реальный пример динамических типов

Я думаю, что у меня есть мой мозг наполовину обернутый вокруг концепции Dynamic Types в С# 4, но не может для меня жизнь выяснить сценарий, где я действительно хотел бы его использовать.

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

Итак, что такое сценарий реального мира, когда использование динамического типа подходит?

Ответ 1

Есть много случаев, когда вы уже используете динамическую типизацию и динамическое связывание сегодня. Вы просто не понимаете этого, потому что все это скрыто за строками или System.Object, так как до С# 4 необходимой поддержки там не было.

Одним из примеров является COM-взаимодействие: COM - фактически полудинамическая система объектов. Когда вы выполняете COM-взаимодействие, многие методы фактически возвращают динамический объект, но поскольку С# не поддерживали их, они возвращались как System.Object, и вам приходилось их бросать самостоятельно, возможно, перехватывая исключения на пути.

Другим примером является взаимодействие с динамически типизированными (или даже нетипизированными) данными, такими как JSON, CSV, HTML, XML-схемы, схематические веб-службы, базы данных схемы (которые, в конце концов, новая горячая). Сегодня вы используете для них строки. XML API будет выглядеть как

var doc = new XmlDocument("/path/to/file.xml");
var baz = doc.GetElement("foo").GetElement("qux");

и т.д. Но как насчет:

dynamic doc = new XmlDocument("/path/to/file.xml");
var baz = doc.foo.qux;

Разве это не выглядит хорошо?

Третий пример - отражение. Сегодня вызов метода посредством отражения выполняется путем передачи строки в InvokeMember (или как бы то ни было, что называется). Разве не лучше, знаете ли, просто вызвать эту чертову вещь?

Затем возникает генерация динамических данных (в основном противоположная второму примеру). Здесь приведен пример создания динамического XML:

dynamic doc = new XmlBuilder();
doc.articles(id=42, type="List", () => {
  article(() => {
    number(42);
    title("blahblubb");});});

Это не так красиво, как эквивалентный Ruby, но это лучшее, что я мог придумать в такое короткое время: -)

И последнее, но не менее важное, интеграция с динамически типизированным языком. Является ли это JavaScript в приложении Silverlight, механизмом пользовательских правил, встроенным в ваше бизнес-приложение или экземпляр DLR, который вы размещаете в своей программе CAD/IDE/текстовом редакторе.

Ответ 2

Вот пример на MSDN:

Многие методы COM допускают изменение типов аргументов и возвращаемого типа, обозначая типы как объекты. Это потребовало явного литья значений для координации с сильно типизированными переменными в С#. Если вы скомпилируете, используя опцию /link (Параметры компилятора С#), введение динамического типа позволяет обрабатывать вхождения объектов в сигнатурах COM, как если бы они были типа динамического, и тем самым избежать большей части кастинга.

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

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

Обновление: немного поиска здесь найдено этот связанный пост.

Ответ 4

Scott Watermasysk написал статью об использовании динамики для сопоставления ключевых слов словаря для драйвера MongoDB С#.

http://simpable.com/code/mongodb-dynamics/

Ответ 5

Я думаю, что другие дали отличные ответы, поэтому я просто хочу добавить этот пример Дэвидом Хэнсоном. В отчете "История" показано наиболее практическое приложение, которое я нашел до сих пор для динамических типов на С#, где он использует их для создания прокси-объектов. В этом примере он создает прокси-сервер, который позволяет создавать исключения из ошибок привязки WPF. Я не уверен, что это также может быть достигнуто в случае привязок WPF с помощью CustomTypeDescriptors и концепций дескриптора свойств в целом, но, независимо от того, я думаю, что использование нового динамического типа С# 4.0 является отличной демонстрацией его возможностей.

Повышение исключений связывания в WPF и Silverlight с .net 4.0 Динамика

Еще одно использование, которое я могу придумать для динамических типов, - создать прокси, которые аналогичным образом могут быть подключены в виде DataContext в WPF или в других местах, где ожидается общий тип объекта, и методы отражения обычно используются для опроса типа, В этих случаях, особенно при построении тестов, может использоваться динамический тип, который затем позволяет динамическим способом вызывать и регистрировать аксессуаров свойств соответствующим образом прокси-объектам без необходимости жесткого кодирования свойств в классе только для тестирования.

Ответ 6

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

Скотт Гензельман - С# 4 и динамическое ключевое слово