Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Игорь Яковлев «Как это работает: DLR»

DotNetRu
October 14, 2015

Игорь Яковлев «Как это работает: DLR»

С версии C# 4.0 появилась возможность использовать динамическую типизацию. Для этого, в платформу .NET была добавлена инфраструктура, позволяющая работать с объектами, тип которых не известен на этапе компиляции. Эта инфраструктура, при поддержке компиляторов и интерпретаторов, позволила обеспечить взаимодействие различных миров: статического и динамического, причем совершенно прозрачно для программиста. К сожалению, данная тема (особенно в русскоязычном сегменте интернет), раскрыта очень поверхностно. В докладе мы рассмотрим устройство динамической типизации платформы .NET с точки зрения C# и подсистемы DLR.

DotNetRu

October 14, 2015
Tweet

More Decks by DotNetRu

Other Decks in Programming

Transcript

  1. Как это работает: DLR dynamic тип в C# или “прорывное”

    направление в .NET ...важно сконцентрировать имеющиеся ресурсы на основных прорывных направлениях… В.В. Путин Игорь Яковлев [email protected]
  2. Зачем нужен DLR? C# VB Ruby Python Динамические Статические •

    Новый способ Interop • Позволяет использовать динамическую типизацию в C#
  3. Свойства типа dynamic в C# dynamic объект - принимает значения

    любого типа dynamic - ссылочный “тип” dynamic - объект может учавствовать в любом* выражении C# тип выражения с dynamic - dynamic* код для выражений с объектом dynamic создается динамически* типизация dynamic объектов: динамическая
  4. Однако Вследствие того, что dynamic является не “родным” для C#,

    можно всегда немного потроллить компилятор: new dynamic(); //compile time error T Foo<T>() where T : new() { return new T(); } … var variable = Foo<dynamic>(); //будет new object()
  5. DLR - dynamic language runtime DLR входит в .Net Framework

    (начиная с версии 4.0) предоставляет API для выполнения программ одного языка в другом операции над объектами с типами которые неизвестны на этапе компиляции
  6. ¬DLR не является частью CLR не подразумевает его поддержку языком

    не вводит в CLR/Framework новых типов (dynamic - ключевое слово) DLR
  7. LINQ Expression Trees Деревья выражений представляют код в виде деревьев,

    где каждая вершина - выражение. Expression.Add Expression.Constant(2) Expression.Constant(3) Выражение 2+3:
  8. Перепишем код для a+b на C#: Фабрика байндера двоичной операции

    Фабрика CallSite Анонимный класс с полем CallSite - синглтон Статическая информация Результат динамической операции Делегат динамической операции
  9. Что такое CallSite Кэширует динамические операции (часть реализации Polymorphic Inline

    Cache) Содержит операцию необходимую для выполнения динамического вызова Создает заглушки для динамических вызовов (делегат Update) Обращается к байндеру динамических вызовов
  10. Что может Target: Выполнить проверку своих аргументов на совместимость с

    операцией Выполнить динамическую операцию Сообщить вызвавшему CallSite результат проверки и операции TARGET
  11. Какой тип у Target?! Target = Action<T1,T2[,T3…]> = Func<T1,T2[,T3…],TResult> T1

    - CallSite T2 - Ресивер [T3,...] - Аргументы TResult - Результат “a+b” - ресивер “a” “A.b()” - ресивер typeof(A) “c.Foo()” - ресивер “c” (MulticastDelegate)
  12. .If ($var1 .TypeEqual System.Int32 && $var2 .TypeEqual System.Int32 && $var2

    == 2) { .Return { (System.Object)($var1 + 2) } } .Else { $callsite.Update() .Return { .Default(System.Int32) } } Какой код внутри Target? Restriction expression Ограничение операции Body expression Тело операции Target - это .Net Expressions Tree v2 скомпилированный в лямбду Пусть Target сгенерирован для операции “a+2”, где a - Int32
  13. Правила (Rules) Restriction expression Ограничение операции Body expression Тело операции

    Rule Правило Комбинация ограничения и тела называется правилом (Rule) Динамический делегат - скомпилированное правило
  14. Откуда берутся правила?! Polymorphic Inline Cache (PIC) Binders Правила (в

    виде скомпилированных делегатов) CallSite берет из нескольких мест
  15. PIC - кэш правил Level 0: Текущий Target у CallSite

    (объем кэша - 1 правило) Level 1: Массив делегатов у CallSite (объем кэша - до 10 правил) Level 2: Словарь кешей в байдере из CallSite (Ключ - тип правила, Значение - массив из 128 правил) DLR PIC - трехуровневый кэш правил (делегатов)
  16. Байндеры Байндер (Binder) Статическая информация о динамическом выражении Набор Bind-методов

    возвращающих правило для переданных аргументов (LINQ Expression Tree v2) PIC Cache Level 2 FallBack методы
  17. Высшая миссия Байндера Байндер (Binder) Набор информации для описания действия

    которое должно быть выполнено Прокладка между резолвером динамических операций и CallSite
  18. 1. Пытается получить готовый делегат через BindDelegate, либо 2. Получает

    правило в виде Expression Tree через вызов Bind 3. Компилирует правило в делегат и добавляет его в PIC Level 2 abstract CallSiteBinder - базовый байндер T BindCore<T>(CallSite<T> site, object[] args) abstract Expression Bind(object[] args, + параметры для Expression Tree) T virtual BindDelegate<T>(CallSite<T> site, object[] args)
  19. abstract DynamicMetaObjectBinder abstract DynamicMetaObject Bind(DynamicMetaObject reciever, DynamicMetaObject[] args) 1. Сопоставляет

    аргументы args их “оберткам” типа DynamicMetaObject (DMO) через DynamicMetaObject.Create(arg) 2. Выделяет первый аргумент (типа DMO) как ресивер 3. Получает DMO с правилом через вызов Bind 4. Строит из DMO выражение .If (Restriction) .Then (.Return Body) ... sealed override Expression Bind(object[] args, + параметры для E.T.)
  20. 12 Разгневанных байндеров DLR поддерживает 12 типов выражений Convert CreateInstance

    DeleteIndex DeleteMember GetIndex GetMember Invoke InvokeMember SetIndex SetMember UnaryOperation BinaryOperation Для каждого выражения есть байндер унаследованный от DMOBinder Для краткости функции и байндеры с __XXX__ в имени заменяются на имена из этого списка
  21. abstract class __XXX__Binder Возвращает reciever.Bind__XXX__(this, args) override sealed DMO Bind(DMO

    reciever, DMO[] args) abstract DMO Fallback__XXX__(DMO target, DMO arg1, [ DMO arg2…,] DMO errorSuggestion) Возвращает Fallback__XXX__(reciever, arg1 [,arg2], null) DMO Fallback__XXX__(DMO reciever, DMO argDMO arg1 [,DMO arg2...])
  22. sealed CSharp__XXX__Binder Вызывает некий RuntimeBinder :) override sealed DMO Fallback__XXX__(DMO

    reciever, DMO arg, [DMO arg2...,] DMO errorSuggestion) И это последний байндер в иерархии
  23. И чего?! oO Остались главные вопросы Что это за бред?

    Что такое DynamicMetaObject (DMO)? Как из нашего object получается его DMO? Что такое FallBack? Кем составляются правила?! Кому нужен IDynamicMetaObjectProvider?
  24. IDynamicMetaObjectProvider Этот скучный парень просто возвращает DynamicMetaObject DynamicMetaObject GetMetaObject(Expression parameter)

    Если наш объект поддерживает этот интерфейс то для объекта можно получить DynamicMetaObject!
  25. DynamicMetaObject::Bind__XXX__ Все 12 разгневанных байндер-методов DMO вызывают FallBack у байндера

    который его вызвал ;) Ну ок, идем обратно в байдер в метод Fallback__XXX__ Однако они virtual...хмммм
  26. RuntimeBinder Парень которого нет в MSDN :) Мы не будем

    приводить уважаемой публике содержание этого треша Содержит реализацию семантического Reflection анализатора .Net Этот парень умеет строить правила для стандартных типов .Net Но ведь типы...эмм...не всегда стандартные!?
  27. Еще раз... Попробуем вспомнить, что происходило и кто кого чего...

    Кто такой CallSite? Кто такие байндеры? Кто такой DMO?
  28. Помоги Даше найти смысл жизни... Выражение с dynamic CallSite.Target(...) CallSite.UpdateAndExecute

    PIC CallSiteBinder Выполнение выражения DMOBinder __XXX__Binder reciever.Bind__XXX__(...) CSharp__XXX__Binder.FallBack аргументы в DMO
  29. Что НЕ вошло в доклад Классы не являющиеся частью прям-ваще

    реализации (ExpandoObject и DynamicObject) Как конкретно происходит построение выражений (лучше не надо :)) Как реализовано взаимодействие с COM (вкраце - COM IDispatch) Что такое и как работает DLR Hosting API (тема на отдельный доклад) Оказывается там есть еще SymPL (целый функциональный язык в спецификации) Реализацию многих мелких деталей (Defer, Stitch, генерацию UpdateAndExecute и тп)
  30. Куда гуглить Можно в гугле - есть статьи но мало

    C# 5 Unleashed - Bart De Smet (на самом деле средненько) Pro DLR in .NET 4 - Chaur Wu (поверхностно) habrahabr - есть пара статей (и вся пара - не очень) dlr.codeplex.com - developer notes (очень хорошо!) В исходники и дебаггер - довольно полное раскрытие темы Можно спросить меня: linkedin.com/in/igoriakovlev Доклад Карлена Симоняна на .NeXT 2014: bit.do/DLR_lecture Поиграть с примерами: bit.do/DLR_examples