... но похоже, что компилятор делает «плохую догадку». Кто-нибудь может мне это объяснить?
Когда вы используете dynamic
, все выражение обрабатывается во время компиляции как динамическое выражение, что заставляет компилятор рассматривать все как динамическое и получать привязку во время выполнения.
Это объясняется в 7.2 спецификации языка C#:
Когда динамические выражения не задействованы, C# по умолчанию использует статическую привязку, что означает, что в процессе выбора используются типы составляющих выражений времени компиляции. Однако если одно из составляющих выражений в перечисленных выше операциях является динамическим выражением, вместо этого операция привязывается динамически.
В основном это означает, что большинство операций (типы перечислены в разделе 7.2 спецификации), которые имеют любой элемент, объявленный как dynamic
, будут оцениваться как dynamic
, а результатом будет dynamic
.
В вашем случае это утверждение:
var settings = new JavaScriptSerializer().Deserialize<dynamic>(json);
Использует динамическое выражение, поэтому оно обрабатывается как динамическое выражение. Поскольку «вызов метода» является одной из операций C#, подлежащих связыванию (7.2), компилятор рассматривает это как динамическую привязку, что приводит к оценке этого как:
dynamic settings = new JavaScriptSerializer().Deserialize<dynamic>(json);
Это, в свою очередь, приводит к динамической привязке выражений DateTime.Parse
, что, в свою очередь, заставляет их возвращать dynamic
.
Ваше «исправление» работает, когда вы делаете DateTime startDate = DateTime.Parse(settings.startDate);
, потому что это вызывает неявное динамическое преобразование (описанное в разделе 6.1.8 спецификации) результата метода DateTime.Parse в DateTime:
Неявное динамическое преобразование существует из выражения типа dynamic в любой тип T. Преобразование динамически связано (§7.2.2), что означает, что неявное преобразование будет выполняться во время выполнения из типа выражения во время выполнения. в T. Если преобразование не найдено, генерируется исключение времени выполнения.
В этом случае преобразование допустимо, поэтому с этого момента вы эффективно переключаете все обратно на статическую привязку.
person
Reed Copsey
schedule
21.02.2012
string
в аргументе аргументаDateTime.Parse()
, например:var startDate = DateTime.Parse((string)settings.startDate)
- person Sergey Kalinichenko   schedule 21.02.2012