2016-01-12 19 views
5

Tôi khá mới đối với C# dynamic từ khóa. Trong một trong những dự án của tôi, tôi đã cố gắng chơi với nó và gặp phải một số hành vi bất ngờ. Tôi quản lý để tạo lại tình hình với đoạn mã sau:Động không tôn trọng loại trả về

class Program 
{ 
    static DateTime? DateOnly(DateTime? time) 
    { 
     return time.HasValue ? (System.DateTime?)time.Value.Date : null; 
    } 

    static void Main(string[] args) 
    { 
     dynamic now = System.DateTime.Now; 
     var date = DateOnly(now); 
     Console.WriteLine(date.Value); // error thrown here 
     Console.Read(); 
    } 
} 

tôi nhận được một RuntimeBinderException nói

'System.DateTime' không chứa một định nghĩa cho 'Giá trị'.

Vì vậy, biến date được coi là DateTime thay vì DateTime?.

Có vẻ như dynamic bằng cách nào đó bỏ qua khai báo loại trả về. Tôi có nên tránh sử dụng var với dynamic không?

Trả lời

5

Vì bạn chuyển một biến số dynamic cho phương thức DateOnly, kiểu trả về cũng trở nên động. Vì vậy, trong trường hợp này, var date của bạn thực sự là dynamic date. Nó chứa một ô trống có giá trị là DateTime, nhưng quyền anh không bảo toàn phần "vô hiệu", vì vậy trên thực tế nó chỉ là một hộp đóng gói DateTime, không có thuộc tính Value. Vì vậy, bạn chỉ nên làm Console.WriteLine(date) để in giá trị.

Như bạn có thể thấy, các loại nullable và dynamic không chơi rất tốt với nhau ...

0

xem thông số chức năng của bạn, bạn đang yêu cầu loại có thể vô hiệu. DateTime (System.DateTime.Now) là kiểu giá trị và kiểu giá trị không được mặc định theo mặc định.

+0

@PoweredByOrange Nullable là một struct. –

2

Có hai vấn đề. Một là date vẫn còn năng động bởi vì phía bên tay phải là một biểu thức năng động. Nếu bạn đã khai báo date với loại cụ thể DateTime? bạn sẽ không thấy điều này. Vấn đề khác là bạn đang trả về một kiểu giá trị nullable và chuyển đổi thành dynamic được coi là boxing. Các loại giá trị không thể bỏ qua không bao giờ được đóng hộp như vậy. Loại giá trị cơ bản chưa được mở để date hoạt động giống như tham chiếu loại object có thể có DateTime hoặc có thể là rỗng, không phải là tham chiếu đến DateTime?. Các chất kết dính sau đó cố gắng giải quyết tài sản Value với DateTime và không thành công. Nếu bạn thử Console.WriteLine(date), tuy nhiên nó sẽ thất bại vì không rõ ràng vì phương pháp đó có quá nhiều quá tải. Vì vậy, bạn sẽ phải làm một cái gì đó như Console.WriteLine((object)date), tại thời điểm đó bạn cũng có thể khai báo dateobject cho ví dụ đơn giản này.

+0

Ý của bạn là "bên tay phải"? –

+0

@ThomasLevesque yea Tôi có nghĩa là người còn lại. Đã sửa. –

Các vấn đề liên quan