179
Примитивный.тип.данных.dynamic
Во время первого вызова оператора
+
значение его аргумента равно 5 (тип
Int32
),
поэтому результат равен 10 (тоже тип
Int32
). Результат присваивается переменной
value
. Затем вызывается метод
M
, которому передается
value
. Для вызова метода
M
компилятор создает код полезной нагрузки, который на
этапе выполнения будет
проверять действительный тип значения переменной, переданной методу
M
. Когда
value
содержит тип
Int32
, вызывается перегрузка метода
M
, получающая параметр
Int32
.
Во время второго вызова
+
значение его аргумента равно
A
(тип
String
), а ре-
зультат представляет собой строку
AA
(результат конкатенации
А
с собой).
Затем
снова вызывается метод
M
, которому передается
value
. На этот раз код полезной
нагрузки определяет, что действительный тип, переданный в
M
, является строковым,
и вызывает перегруженную версию
M
со строковым параметром.
Когда тип поля, параметр метода, возвращаемый тип метода или локальная
переменная снабжаются пометкой
dynamic
, компилятор
конвертирует этот тип
в тип
System.Object
и применяет экземпляр
System.Runtime.CompilerServices.
DynamicAttribute
к полю, параметру или возвращаемому типу в метаданных. Если
локальная переменная определена как динамическая, то тип переменной также
будет типом
Object
, но атрибут
DynamicAttribute
неприменим к локальным пере-
менным из-за того, что они используются только внутри метода. Из-за того, что
типы
dynamic
и
Object
одинаковы, вы не сможете создавать методы с сигнатурами,
отличающимися
только типами
dynamic
и
Object
.
Тип
dynamic
можно использовать для определения аргументов типов обоб-
щенных классов (ссылочный тип), структур (значимый тип), интерфейсов, деле-
гатов или методов. Когда вы это делаете, компилятор конвертирует тип
dynamic
в
Object
и применяет
DynamicAttribute
к различным частям метаданных, где это
необходимо. Обратите внимание, что обобщенный код,
который вы используете,
уже скомпилирован в соответствии с типом
Object
, и динамическая отправка не
осуществляется, поскольку компилятор не производит код полезной нагрузки
в обобщенном коде.
Любое выражение может быть явно приведено к
dynamic
, поскольку все вы-
ражения дают в результате тип, производный от
Object
1
. В общем случае компи-
лятор не позволит вам написать код с неявным приведением
выражения от типа
Object
к другому типу, вы должны использовать явное приведение типов. Однако
компилятор разрешит выполнить приведение типа
dynamic
к другому типу с ис-
пользованием синтаксиса неявного приведения.
Object o1 = 123; // OK: Неявное приведение Int32 к Object (упаковка)
Int32 n1 = o1; // Ошибка: Нет неявного приведения Object к Int32
Int32 n2 = (Int32) o1; // OK: Явное приведение Object к Int32 (распаковка)
dynamic d1 = 123; // OK: Неявное приведение Int32 к dynamic (упаковка)
Int32 n3 = d; // OK: Неявное приведение dynamic к Int32 (распаковка)
1
И как обычно, значимый тип будет упакован.