Это так же безопасно, как и вы.
Под капотом переменная типа dynamic
на самом деле имеет тип object
. Так что ничего особенного не происходит, когда вы назначаете ему "String"
, 123
или new Action<string>(…)
. Возможно, вы уже знаете, что вы легко можете сделать то же самое с любой object
переменной. Единственная магия, которая происходит, - это бокс для значений, типизированных для значений (например, 123
), но опять же, это не является чем-то особенным для dynamic
, но произошло с такими присваиваниями, как object x = 123;
, начиная с первой версии .NET.
(Для ясности: вы не меняете никакого значения, когда повторно назначаете свою dyn
переменную. Вы просто делаете dyn
ссылку на другое значение.)
Волшебство, которое случается с dynamic
, - это позднее связывание. То есть каждый раз, когда вы вызываете метод, свойство, оператор и т. Д. Для такой переменной, фактический метод, свойство, оператор и т. Д. Еще не известен во время компиляции; он выбирается во время выполнения. Для каждого такого вызова компилятор генерирует код, который проверяет тип текущего значения переменной и пытается выбрать подходящий метод, свойство, оператор и т. Д. Для вызова. Если такой найден, он вызывается; в противном случае вы получите исключение.
Давайте посмотрим на другой пример:
dynamic a = 123;
Console.WriteLine(a * 2); // OK
dynamic b = "123";
Console.WriteLine(b * 2); // will throw an exception
Здесь интересно исключение, выброшенное вторым блоком:
RuntimeBinderException
: оператор *
нельзя применять к операндам типа string
и int
.
Вы не получили какое-то арифметическое исключение, потому что никогда даже не пытались умножить "123"
на 2
. Среда выполнения не смогла даже найти подходящий *
оператор для вызова! Среда выполнения проверила типы b
(string
) и 2
(int
) и попыталась найти оператор *
для этих двух типов, но не смогла его найти… следовательно, исключение.
(То же самое, конечно, произошло с a * 2
; там среда выполнения увидела, что a
имеет тип времени выполнения int
(поскольку он ссылается на упакованное целое число 123
в тот конкретный момент), и то же самое произошло с 2
, и был найден и, таким образом, вызван оператор *
для двух int
s .)
Кстати, из-за природы dynamic
переменных с поздним связыванием (т.е. подходящие действия с ними выясняются только во время выполнения), IntelliSense (функция времени компиляции) с ними не работает.
person
stakx - no longer contributing
schedule
28.08.2014