Pull to refresh

Comments 29

Вообще говоря, спорное нововведение. Мне совершенно не хочется, чтобы C# «оскриптился»…
Соглашусь, из-за этого нововведения пропадает много вкусностей, начиная с IntelliSense и кончая тем, что в любой момент может выплюнутся такой runtime-exception, даже, если код успешно скомпилировался.
Но, собтсвенно, никто и ничего не мешает его не использовать.
Вобщемто выбор есть всегда.
Но ведь найдутся «мастера», которые будут пихать динамические объекты везде где вздумается.

К тому же, как Вы правильно заметили, возникает опасность появления runtime-exception'ов. Это значит, что вызовы методов динамических объектов должны находится в блоке try-catch или каким-то образом декларировать это на уродвне описания метода. В отличие от Java, в C# используется более мягкий подход к обработке исключений. Компилятору безразлично, перехватили ли вы исключение или нет. Единственный способ указать, что метод может выбрасывать RuntimeBinderException — использовать xml-документацию, на которую всем (в том числе, компилятору) по большому счёту начхать. В конечном итоге, невнимание к обработке исключений «RuntimeBinderException» может завершиться падением приложения.
Да, это, конечно, так.
Но живут ведь люди применяя тот же Reflection — а там тоже опасность исключений велика. Главное все правильно продумать.
Reflection позиционируется как инструмент для профессионалов, он громоздкий и неудобен в использовании. Для его правильного и адекватного применения нужно обладать довольно серьёзным опытом разработки на C#.
А dynamic-objects — это такой синтаксический сахар, который возлагает на себя все проблемы, связанные с reflection-ом. Мне кажется, что эта фича должна понравиться тем, кто решил начать изучать C# после того, как поигрался немного с JavaScript.
Насколько я понял из статьи, в которой автор провел второе тестирование, dynamic — не просто сахар для Reflection, иначе он не получил бы таких кардинальных различий:
Compile Time Bound: 6 ms
Dynamically Bound with dynamic keyword: 45ms
Dynamically Bound with MethodInfo.Invoke — 10943ms
Dynamically Bound with DynamicMethod — 8ms

MethodInfo.Invoke — это и есть Reflection
На сколько я понял, это всё-таки рефлекшн, но не через MethodInfo.Invoke, а с помощью генерации делегата, который вызывает нужный метод. Это работает быстрее, поскольку параметры делегата жёстко заданы и нет необходимости передавать их в виде массива, а потом матчить их в рантайме на параметры функции, как это происходит в случае MethodInfo.Invoke.
Но как видно из приведённой Вами таблицы, ручная генерация делегатов с помощью класса DynamicMethod (который появился ещё в .NET 2.0) работает даже быстрее, чем динамические объекты в C# 4.0.
Не только. typeof(TestClass).GetMethod("TestMethod1"); — это тоже Reflection.
Просто в случае MethodInfo.Invoke это чисто позднее связывание, в то время, как DynamicMethod — «комбинированный подход».

Если вам интересно, могу порекомендовать эту статью.
dynamic-ом не будут злоупотреблять из-за того, что с ним не заработает IntelliSense.

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

А Exception вполне может выкинуть и сам вызываемый метод, что ж поделаешь.
UFO just landed and posted this here
Что-то не нравятся мне эти нововведения. На днях почитали «New features in C# 4.0», чувствую, прослыву ретроградом. Ничего действительно полезного для себя так и не нашел. Разве что Generic Covariance.
Старый добрый DynamicMethod в пять раз уделал все «новинки».
я думаю это будет использоваться скорее как замена гиморной рефлексии
Пример:
dynamic object = GetDynamicObject(…);
object.Method(7);
UFO just landed and posted this here
Народ… вы, мне кажется, не воткнули в прелести позднего инициирования. =))
Я больше чем уверен, что эта фишка разработана по ооочень многочисленным просьбам, и сам рад её появлению!
Вы когда-нибудь работали с Офисом (как самыыый часто встречаемый пример)? или со сторонними сервисами, через СОМ?
чтобы юзать такой сервис, надо было писать охрененную заглушку, чтобы взаимодействовать с ними! нужно было прописывать пути строго к тому, где лежат реализации (да хоть длл)? а как же версионность?
Написал ты прогу под 2000 офис, там одни длл с интерфейсными методами. пытаешь запустить её где стоит 2007… ФИГ! она не заработает!
А так… просто вызываешь у сервиса метод по имени и все! ты только привязан к сигнатуре прототипа и все =)

Так что поверьте «dynamic » — это тема!!!
как мне нравятся минусующие тут люди… =))))
второй раз не выдерживаю и решаюсь что-нибудь написать… и снова минуса… причем оба раза невыдерживал как раз из-за совсем дилетантских ля=ля на тему =)))

но желание писать сейчас отпало ещё больше. Удачи =))
Дело скорее всего в том, что многие люди (в том числе и я) считают ± как согласен/не согласен, а не хороший/плохой комментарий.
Но зачем ради этого вводить в язык специальный тип? Это ведь бывает нужно очень редко!
Вполне можно было бы обойтись каким-нибудь самописным фреймворком. Вызовы можно оформить так:

class FooBar {
public void Method1(string param1, string param2) {...}
}

var x = new FooBar();
Dynamic o = new Dynamic(x);
o[«Method1»](param1, param2);

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

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

все равно что: зачем foreach, если есть for?

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

и никакого «оскрипчивания» не происходит… С# строготипизированный язык, и чтобы использовать позднее связывание надо или левой рукой чесать правое ухо, или дать возможность нейтивно его юзать.
Все правильно. Самому приходилось работать с 1С 7.7, писал веб сервис один, который с ней работает. Так я этот сервис написал на VB, так как там это все есть и код получился в разы короче и интуитивно понятнее.
100% верно. Чем сложнее приложение тем больше там нужно позднего связывания, анонимных типов и прочих «фишек», а так как они сделаны от MS то они намного лутче чем бы ми их сами «на коленке» писали…

PS: об этом говорит опыт Smalltalk…
www.smalltalk.ru/articles/smalltalk.html
Вот расскажите, какая связь между сложностью приложения и, к примеру, анонимными типами?
Почитайте статью о Smalltalk, там отрожено мнение с которым я абсолютно солидарен :)
Не увидел там никакого мнения.

Коли речь зашла о статьях, то прочитайте статью Брукса «No Silver Bullet — Essence and Accident in Software Engineering»: там как раз по поводу Essential и Accidental Complexity. Вот эти все «фишки», использованные «for the hell of it», вообще говоря, — привнесение Accidental Complexity.
Хорошо когда оно есть, даже если оно тебе и не надо. Плохо когда надо — а нету
Когда этого «оно» становится слишком много
и оно тебе не надо — это плохо/некомфортно.
(Из-за чего я и отказался от менедж с++)
Sign up to leave a comment.

Articles