Skip to content

Instantly share code, notes, and snippets.

@eterekhin
Last active October 7, 2019 07:51
Show Gist options
  • Save eterekhin/1bcac0b640fa8b98f8dc356c427aacfd to your computer and use it in GitHub Desktop.
Save eterekhin/1bcac0b640fa8b98f8dc356c427aacfd to your computer and use it in GitHub Desktop.

Тезисы

??? Тип dynamic можно использовать для определения аргументов типов обобщенных классов (ссылочный тип), структур (значимый тип), интерфейсов, делегатов или методов. Когда вы это делаете, компилятор конвертирует тип dynamic в Object и применяет DynamicAttribute к различным частям метаданных, где это необходимо. Обратите внимание, что обобщенный код, который вы используете, уже скомпилирован в соответствии с типом Object, и динамическая отправка не осуществляется, поскольку компилятор не производит код полезной нагрузки в обобщенном коде ???

Что динамическая отправка не осуществляется???

1)Как компилятор генерирует и обрабатывает вызовы dynamic кода

Компилятор считает что это типа object , генерирует код полезной нагрузки, который в run-time сможет определить какой метод вызвать:

dynamic q = "213";
q + "123"
или 
dynamic q = 123
q + 123

Будет вызван либо метод сложения либо для строк, либо для целых чисел Если объект используется в foreach то компилятор пытается привести его к IEnumerable, если в using, то происходит cast к IDisposable Привязку методов и полей во время выполнения осуществляет run-time binder, разные языки реализуют своих компоновщиков для привязки в run-time, может показаться что постоянные вызовы динамического метода это очень непроизводительно, потому что binder должен каждый раз разрешать тип объекта, но все же проведены определенные меры, например, весь код полезной назрузки выполненный для привязки будет помещен в анонимную сборку динамических методов, для того, чтобы в следующий раз, при вызове этого кода с тем же типом(который скрывается за dynamic), не пришлось генерировать его снова еще раз

В чем отличается вызов динамического метода на типе который реализует IDynamicMetaObjectProvider и не реализует его

Если происходит вызов на типе реализующем IDynamicMetaObjectProvider, то в run-time вызвав GetMetaObject(), можно получить DynamicMethodObject, который может обработать все вызовы методов и привязки для этого объекта Если же нет, то для привязки методов будет использоваться рефлексия Например в C# опреден ExpandoObject, который реализует IDynamicMetaProvider

3) Как настроить DynamicMetaObject?

Можно унаследовать свой тип от DynamicObject, в нем доступны виртуальные методы привязки, которые можно переопределить, например, TrySetMember, который будет вызываться при таких обращенияз:

 public class TestDynamicObject : DynamicObject
    {
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            Console.WriteLine($"name:{binder.Name},value:{value}");
            return base.TrySetMember(binder, value);
        }
    }
...
       public void Method()
       {
           dynamic q = new TestDynamicObject();
           q.TestField = "testField";
           // name: TestField, value:"testField"
       }

Что нужно сделать чтобы компилятор научился работать с dynamic?

Загрузить в домен приложения Microsoft.CSharp.dll, также вместе с ней будут загружены System.dll и System.Core.dll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment