Как стать автором
Обновить

Комментарии 35

Вы вроде вызываете метод SomeMethod():
dynamic dobj = new DO();
dobj.SomeMethod();

а исключение у вас вылетает для другого метода:
'DynamicObjectAbuse.DO' does not contain a definition for 'NonExistentMethod'

Так и должно быть? =) Студии 2010 к сожалению нет под рукой чтобы самому проверить(
Так не должно быть :-) Это опечатка (равно как и в статье на gotdotnet) ;-)
Нет, автор видимо немного ошибся.
Я только что проверил текст исключения указывает, что именно вызываемый метод не существует:
Shell.ShellForm.Dyn does not contain a definition for 'SomeMethod'

Да, еще автор забыл упомянуть, что нужно добавить референс на Microsoft.CSharp. Иначе компилятор ругается, что ему не хватает типа RuntimeBinder.Binder:
Error 1 Predefined type 'Microsoft.CSharp.RuntimeBinder.Binder' is not defined or imported
Error 2 One or more types required to compile a dynamic expression cannot be found. Are you missing references to 'Microsoft.CSharp.dll 
and System.Core.dll'
?

И, само собой, надо было указать, что фреймворк нужен не ниже 4 версии.
В своё время я считал перечисленные возможности «фишкой» Objective-C. А теперь вижу что современные технологии стремятся в реализации таких фишек у себя, это приятно.
Очень, очень важная мысль:
Если коротко, то вариантов использования очень много, хотя безусловно “каноническим” программированием это безобразие не назвать. Уверен, что отсутсвие статических проверок может при неграмотном использовании наплодить кучу недетектируемых багов, поэтому мой вам совет – будьте осторожны!


Тут все же надо понимать что добавление такого функционала (а особенно — использование его не по делу) — это как комбинирование губной гармошки с опасной бритвой — инструмент получается странный и требует особой сноровки в обращении =).
ExpandoObject – это вообще лебединая песня.
Фразеологизм лебединая песня (песнь) обязан своим происхождением народному поверью, по которому лебедь поет в своей жизни один раз – перед смертью. Отсюда и установившееся его значение: «Последнее, обычно наиболее значительное, произведение кого-либо; последнее проявление таланта, способностей и т. п.» («Фразеологический словарь русского языка»).

символично, ёпт
>Естественно, что методы такая штука сериализовывать не будет.
Как можно сериализовать метод?
О, это rocket science. Наверное если это не Expression<T> то вообще никак, если это выражение то можно сериализовать граф. Сам я конечно не пробовал :)
Уточню, что динамическое поведение характерно не только для унаследованных от Dynamic object классов.
«At runtime, if a dynamic object implements IDynamicMetaObjectProvider, that interface
is used to perform the binding. If not, binding occurs in almost the same way
as it would have had the compiler known the dynamic object’s runtime type. These
two alternatives are called custom binding and language binding.» — C# 4.0 in a nutshell страница 162

И еще: все вызовы перегруженных методов разрешаются во время выполнения. Среда определяет фактический тип dynamic object и делает максимально подходящий вызов,
т.е. если у вас есть SomeMethod(object a,int b) и SomeMethod(int a, int b),
то
Dynamic a=3;

SomeMethod(a,4); вызовет вторую перегрузку во время выполнения.
Честно говоря, все эти штуки всё дальше переводят C# из разряда языков «ну, если скомпилилось, то есть хоть какая-то минимальная надежда, что заработает» в разряд «то, что скомпилилось вообще нифига не значит, поскольку весь реальный код будет генериться потом и на лету». Ладно, если я по ходу отладки столкнусь с сообщением в духе «нет такого метода в этом классе» или «свойство такое-то не принадлежит классу». А если пользователь потом, уже после релиза? Все-же в классическом С++ (и поначалу в .NET) такого не было, что вызывало как-то больше уверенности.
Никто не заставляет этим пользоваться. Другое дело что пользоваться этим так и так будут, точно так же как например пользуются PostSharp (что тоже небезопасно).
Есть предположение, что даже удачно скомпилированная программа не гарантирует работоспособности.
Работоспособность гарантируют юнит-тесты.

Отсюда вытекает первый постулат динамических языков программирования — строгая типизация не нужна, нужны юнит-тесты.
лого на Google Wave смахивает
Понятно теперь откуда у Гугля ноги ростут :)
Ну этим просто надо аккуратно пользоваться. Описаны паттерны, которые позволяют с использованием dynamic реализовать их намного красивее. Получившийся функционал также удобнее для дальнейшего использования.
Также сценарии, где используется рефлексия теперь будут удобнее в написании.
Кстати dynamic быстрее рефлексии.
Вот еще интересное, чтобы расставить все на свои места (из той же книги):
«Its
primary role is to provide runtime services to unify dynamic programming—in both
statically and dynamically typed languages. This means that languages such as C#,
VB, IronPython, and IronRuby all use a common protocol for calling functions dynamically,
allowing them to share libraries and call code written in other languages.
The DLR also makes it relatively easy to write new dynamic languages in .NET.
Instead of having to emit IL, dynamic language authors work at the level of expression
trees (the same expression trees in System.Linq.Expressions that we talked about in
Chapter 8).
The DLR further ensures that all consumers get the benefit of call-site caching, an
optimization whereby the DLR avoids unnecessarily repeating the potentially expensive
member resolution decisions made during dynamic binding.»
все что тут описано уже давно есть, например, в Руби. Зачем MS делает очередного монстра из красивого и стройного C# – мне не совсем понятно. Лучше бы улучшали виртуальную машину для увеличения скорости работы динамических языков и все было бы замечательно: нужна скорость – пишешь на C#, нужен динамизм – на IronRuby.
Dynamic и вводили, вроде бы, для более качественной поддержки вещей типа IronRuby\IronPython.

Просто т.к. ручки торчат наружу — всегда найдется кто-либо кто дернет за них
А представляете что будет когда метапрограммирование в C# появится?
«Дисциплина — главный козырь коммунизма, движущая сила армии.»

По рукам себя просто надо чаще бить =).
BTW Пример с DynamicXMLNode для меня иллюстрировал обратное — как раз когда видишь вот такие вещи

xe.Elements(«People»).Element(«Dmitri»).Attributes(«Name»).Value; // WTF?


Сразу возникает 2 желания — во первых проверить все промежуточные результаты, во вторых — переписать по-другому, чтобы была только одна проверка, благо XPath никто не отменял, типа такого

xe.XPathSelectElement("./People//Dmitri[@Name]");


А второй синтаксис, xe.people.dmitri.name, имхо ужасен, хотя и создает иллюзию статической типизации
xe.people.dmitri.name


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

Или я отстал и хардкодинг уже хорошо?
во-во. Все велосипеды от незния матчасти. А если null где-то в это цепочек. А XPath для чего?
Вы о чем?
Если вы посмотрите код DynamicXMLNode, то вроде как там специально делается такой сценарий (xe.people.dmitri.name), путем некоторых уловок с DynamicObject.
Мне же не нравится такой сценарий именно из-за того, что создается иллюзия статической типизации ( выглядит понтово но не более), в то время как даже неаккуратный
xe.Elements(«People»).Element(«Dmitri»).Attributes(«Name»).Value;
вызывает желание сделать проверки ( именно из-за того что использует в том числе хардкодинг имен).

Или я неправильно понял суть ваших комментариев.
Иллюзия статической типизации тут везде, это как раз считается бонусом т.к. дает писать более простой код.
Кем считается? для кого более простой? человек впервые увидевший конструкцию xe.people.dmitri.name имхо просто припухнет, пытаясь понять что есть что и кто…
В том-то и дело, что людям иногда нужен динамизм без дополнительных языков
как я вижу, C# уверенно движется в сторону javascript :)
пример фиговый. вместо xpath предлагается какой-то убогий дсл…
Что-то мне получаемый код кажется катастрофически непрозрачным. А где непрозрачность, там тяжелые отладка, развитие и сопровождение. Так ли нужны эти прибамбасы? Сила в простоте.
Нужны, но редко. Я работал с рефлексией серьезно когда писал динамические запросы в LinQ (а он как мы знаем статически типизированный). В других случаях тоже что-то было, но по чуть чуть и не помню уже.
Я к тому что например dynamic упростит работу с рефлексией.
А можно ли как-то dynamic использовать в visual c++?
Нет, конечно. Точноее может в C++/CLI/CX что-нибудь такое и сделали, но в обычном С++ это невозможно.
Да, я имел ввиду C++/CLI, например, такая проблема: в c# можно создать поле с динамическим объектом, например
public dynamic DynObject
а потом обращаться
DynObject.item
вместо
DynObject.Collection[«item»]
А как этот же функционал использовать в C++/CLI?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории