Место вызова на .NET Framework

Когда компилятор встречает динамическое выражение, он не имеет никакого представления о том, кто или что будет оценивать это выражение во время выполнения. Например, рассмотрим следующий метод:

public dynamic Foo (dynamic x, dynamic y)

{

return x / у; // Динамическое выражение

}

Переменные x и у могут быть любым объектом CLR, объектом СОМ или даже объектом, размещенным в каком-нибудь динамическом языке. Таким образом, компилятор не может применить обычный статический подход с выпуском вызова известного метода известного типа. Вместо этого компилятор выпускает код, в конечном счете, дающий дерево выражения, которое описывает операцию, управляемую местом вызова (call site), к которому DLR привяжется во время выполнения.

Место вызова, в сущности, действует как посредник между вызывающим и вызываемым компонентами. Место вызова представлено классом CallSiteo из System.Core.dll. Это можно увидеть, дизассемблировав предыдущий метод; результат будет выглядеть примерно так:

static CallSite> divideSite;

[return: Dynamic]

public object Foo ([Dynamic] object x, [Dynamic] object y)

{

if (divideSite == null) divideSite =

CallSite

Microsoft.CSharp.RuntimeBinder.Binder.BinaryOperation ( CSharpBinderFlags.None,

ExpressionType.Divide,

) ) ;

return divideSite.Target (divideSire, x, у);

}

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

Затем происходит действительный динамический вызов за счет обращения к полю Target (делегат) места вызова с передачей ему операндов х и у.

Обратите внимание, что класс Binder является специфичным для С#. Каждый язык с поддержкой динамического связывания предоставляет специфичный для языка связыватель, который помогает DLR интерпретировать выражения в манере, присущей этому языку и не вызывающей удивление у программиста. Например, если мы вызываем метод Foo с целочисленными значениями 5 и 2, связыватель C# будет гарантировать, что мы получим в результате 2. С другой стороны, связыватель VB.NET приведет к возврату 2.5.

Рекомендуем к прочтению →  Характеристики твердотельного SSD диска
Понравилась статья? Поделиться с друзьями:
hi-tech новости
Добавить комментарий

:) :D :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

Adblock
detector