2010-08-24 27 views
13

Tôi có theo phương pháp (giản thể):Cast trong phương pháp tổng quát để DateTime

private static string GetStringFromValue<T>(T val) 
{ 
    if (typeof(T) == typeof(DateTime)) 
    { 
     return string.Format("{0}", ((DateTime)val).Year.ToString("0000")); 
    } 
    return string.Empty; 
} 

Tại các diễn viên "(DateTime) val" Tôi nhận được lỗi sau:

Cannot cast expression of Type 'T' to type 'DateTime'

gì có thể làm gì để truy cập thuộc tính Năm của tham số DateTime?

CẬP NHẬT: Cảm ơn tất cả các câu trả lời rất nhanh của bạn. Phương thức này (và tên phương thức) thực sự được (!) Đơn giản hóa để hiển thị chính xác vấn đề của tôi và để mọi người chỉ sao chép & dán nó vào studio trực quan của riêng mình. Nó chỉ là tôi muốn thêm một số loại giá trị cụ thể nếu loại là một DateTime. Bên cạnh đó 99% của phương pháp là như nhau.

+1

Tại sao bạn viết 'String, Format (" {0} ", cái gì đó)'? – SLaks

+0

Không chỉ vậy. 'something.ToString()'. – recursive

+0

Năm không phải là giá trị duy nhất tôi muốn nhận được. Nhưng tôi đã đơn giản hóa phương pháp. Hoặc là nó sai mà tôi sử dụng String.Format ở tất cả? Nó có hiệu suất tốt hơn và dễ đọc hơn: x.Year + ":" + x.Month + ":" + ..... – Chris

Trả lời

24

Thay đổi nó để

return string.Format("{0:yyyy}", val); 

Để trả lời câu hỏi, trình biên dịch không nhận ra rằng TDateTime.
Để thực hiện dàn diễn viên này, bạn cần phải cast qua object, như thế này:

return ((DateTime)(object)val).Year.ToString("0000"); 
+5

Tất nhiên, nếu bạn bỏ qua đối tượng, sẽ có bước đánh đấm & unboxing. –

+0

@ James: AFAIK, không có cách nào để tránh điều đó mà không tạo ra một phương pháp riêng biệt. – SLaks

+1

Tôi đồng ý, nhưng cần lưu ý. –

1

SLaks loại nhanh hơn tôi. :)

Nhưng hãy để tôi thêm: bạn có thể muốn suy nghĩ lại việc triển khai của mình, tại đây, tùy thuộc vào những gì bạn đang cố gắng đạt được. Tôi cho rằng lý do để có một phương thức GetStringFromValue chung là phát ra các chuỗi cụ thể từ các kiểu khác nhau. Nhưng điều đó sẽ kết thúc một chút lộn xộn một khi bạn có, nói rằng, một tá các loại khác nhau trong đó.

Nếu chúng là các loại Hệ thống, chẳng hạn như DateTime, string.Format() có thể xử lý tất cả chúng, với các chuỗi định dạng thích hợp. Nếu chúng là các kiểu của riêng bạn, hãy cân nhắc việc ghi đè các phương thức ToString() của chúng.

Dù bằng cách nào, chi tiết hơn một chút về vấn đề bạn đang giải quyết sẽ tạo ra câu trả lời thú vị.

6

Tôi biết bạn nói ví dụ đã được đơn giản hóa, nhưng xem xét xử lý nó như thế này:

private static string GetStringFromValue(DateTime val) 
{ 
    return string.Format("{0}", val.Year.ToString("0000")); 
} 

private static string GetStringFromValue<T>(T val) 
{ 
    return string.Empty; 
} 

Các quá tải DateTime là phù hợp nhất khi một DateTime thực tế được thông qua, và phiên bản generic sẽ được sử dụng cho everthing khác. (Bạn thậm chí có thể bỏ chung cho cái thứ hai, và chỉ sử dụng một đối tượng)

+0

upvote cho các phương pháp riêng biệt cho từng loại. Nó sẽ tốt hơn nếu sử dụng {0: yyyy} thay vào đó? –

+0

hoặc đơn giản là val.ToString ("yyyy") –

+1

@gbogumil: val.ToString ("yyyy") - Điều này sẽ cho tôi lỗi: Phương thức 'ToString' có 0 tham số nhưng được gọi với 1 đối số – Chris

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