2012-08-08 29 views
6

Tôi đang viết một phương thức để thực hiện chuyển đổi kiểu thông minh - sử dụng ToString() nếu tham số kiểu xảy ra là một chuỗi, nếu không thì sẽ trả về null nếu dàn diễn viên không công việc. Về cơ bản nhận được nhiều thông tin trong số v nó có thể mà không cần ném một ngoại lệ.Đúc chuỗi thành kiểu generic là một chuỗi

tôi kiểm tra xem T thực sự là một string trước khi tôi cố gắng dàn diễn viên, nhưng trình biên dịch vẫn không phải là một fan hâm mộ:

Cannot convert type 'string' to 'T' 

Và đây là phương pháp của tôi:

public T? Convert<T>(object v) 
{ 
    if (typeof(T) == typeof(string)) { 
    return (T)v.ToString(); // Cannot convert type 'string' to 'T' 
    } else try { 
     return (T)v; 
    } catch (InvalidCastException) { 
    return null; 
    } 
} 

Cũng cho tôi biết nếu đây là một loại tội lỗi không thể tha thứ được. Tôi đang sử dụng nó để đối phó với một số cấu trúc dữ liệu có thể có các loại hỗn hợp.

+0

Có các vấn đề khác. Phương thức của bạn không thể có kiểu trả về 'T?' Khi không có ràng buộc về 'T'. Ví dụ, không có gì gọi là 'string? 'Vì chuỗi là một kiểu tham chiếu. –

Trả lời

25

Bạn về cơ bản cần phải đi qua object khi đúc để một kiểu generic:

return (T)(object) v.ToString() 

return (T)(object) v; 

Tôi sẽ sử dụng is thay vì bắt một số InvalidCastException.

Xem Eric Lippert's recent blog post để biết thêm chi tiết về lý do tại sao điều này là cần thiết.

Đặc biệt:

Bởi vì trình biên dịch biết rằng cách duy nhất chuyển đổi này có thể là có thể thành công nếu là U là bool, nhưng U có thể bất cứ điều gì! Trình biên dịch giả định rằng hầu hết thời gian U sẽ không được xây dựng với bool và do đó mã này gần như chắc chắn là một lỗi và trình biên dịch đưa sự thật đó đến sự chú ý của bạn.

(thay thế T cho Ustring cho bool ...)

+1

Sẽ không 'là' là sự lựa chọn tốt hơn ở đây? –

+1

@SteveCzetty: Chúng tôi không biết rằng 'T' là một loại nullable, vì vậy' as' sẽ không hoạt động (IIRC). –

+0

Điểm tốt. Mặc dù tôi không nghĩ rằng 'is' sẽ hoạt động, trừ khi' T' bị ràng buộc vào một 'lớp'. (IIRC, cũng) –

2

Bạn cần phải cast chuỗi của bạn như object như kiểu trả về của bạn là chung chung tức là

return (T)(object)v.ToString(); 
+1

Đó không phải là quyền anh. Không có loại giá trị nào liên quan. –

+0

@JonSkeet vâng sử dụng từ sai! Có nghĩa là để nói diễn viên ... – James

0

Cố gắng chuyển đổi sang object trước khi chuyển đổi để T

return (T)(object)v; 
0
using System.ComponentModel; 

...

public T Convert<T>(object v) { 
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(v); 
} 

Cảnh báo, điều này sẽ ném một ngoại lệ nếu không có chuyển đổi nào tồn tại giữa T và đối tượng chứa trong câu.

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