.. nhưng có vẻ như trình biên dịch đang thực hiện 'phỏng đoán xấu'. bất cứ ai có thể giải thích điều này với tôi?
Khi bạn sử dụng dynamic
, toàn bộ biểu hiện được điều trị tại thời gian biên dịch như một biểu hiện năng động , gây ra trình biên dịch để điều trị tất cả mọi thứ như năng động và có được thời gian chạy ràng buộc.
này được giải thích trong 7.2 của đặc tả C# Ngôn Ngữ:
Khi không có biểu hiện động có liên quan, C mặc định # để tĩnh ràng buộc, có nghĩa là các loại thời gian biên dịch các biểu thức thành phần được sử dụng trong việc lựa chọn quá trình. Tuy nhiên, khi một trong các biểu thức cấu thành trong các hoạt động được liệt kê ở trên là một biểu thức động, thì hoạt động này thay vì bị ràng buộc động.
này về cơ bản có nghĩa là hầu hết các hoạt động (các loại được liệt kê trong phần 7.2 của spec) mà có bất kỳ yếu tố đó được khai báo là dynamic
sẽ được đánh giá như dynamic
, và kết quả sẽ là một dynamic
.
Trong trường hợp của bạn, tuyên bố này:
var settings = new JavaScriptSerializer().Deserialize<dynamic>(json);
Sử dụng năng động, vì vậy, nó getst reated như một biểu hiện năng động. Vì "Gọi phương thức" là một trong các hoạt động của C# bị ràng buộc (7.2), xử lý biên dịch này là động ràng buộc, mà nguyên nhân này để đánh giá để:
dynamic settings = new JavaScriptSerializer().Deserialize<dynamic>(json);
này, đến lượt nó, làm cho DateTime.Parse
biểu phải năng động ràng buộc, do đó làm cho chúng trở dynamic
.
"sửa chữa" của bạn hoạt động khi bạn làm DateTime startDate = DateTime.Parse(settings.startDate);
vì lực lượng này một chuyển đổi động ẩn (được mô tả trong phần 6.1.8 của spec) về kết quả của phương pháp DateTime.Parse đến một DateTime:
Một chuyển đổi động tiềm ẩn tồn tại từ một biểu thức của kiểu động với bất kỳ loại T. Chuyển đổi được tự động ràng buộc (§7.2.2), có nghĩa là một chuyển đổi tiềm ẩn sẽ được tìm kiếm tại thời gian chạy từ kiểu thời gian chạy của biểu thức T. Nếu không tìm thấy chuyển đổi, ngoại lệ thời gian chạy được ném.
Trong trường hợp này, chuyển đổi hợp lệ, vì vậy, bạn chuyển tất cả mọi thứ trở lại thành ràng buộc tĩnh từ đó trở đi.
"Mọi người có thể giải thích điều này cho tôi không?" có lẽ là "Liệu Eric Lippert có thể giải thích điều này cho chúng ta không?" – dasblinkenlight
Điều đó làm tôi ngạc nhiên. Tôi không tin bạn cho đến khi tôi thử nó! :-) – Simon
Một cách khác để giải quyết vấn đề này là buộc loại 'string' trên đối số * của' DateTime.Parse() ', như sau:' var startDate = DateTime.Parse ((string) settings.startDate) ' – dasblinkenlight