2009-11-29 34 views
5

Tôi có một lớp chung và tôi muốn thực thi các trường hợp của tham số kiểu luôn là "có thể chuyển đổi"/chuyển đổi từ Chuỗi. Có thể làm điều này mà không ví dụ bằng cách sử dụng một giao diện?Làm cách nào để kiểm tra xem có tồn tại ẩn hoặc rõ ràng không?

có thể thực hiện:

public class MyClass<T> where T : IConvertibleFrom<string>, new() 
{ 
    public T DoSomethingWith(string s) 
    { 
     // ... 
    } 
} 

thực hiện lý tưởng:

public class MyClass<T> 
{ 
    public T DoSomethingWith(string s) 
    { 
     // CanBeConvertedFrom would return true if explicit or implicit cast exists 
     if(!typeof(T).CanBeConvertedFrom(typeof(String)) 
     { 
      throw new Exception(); 
     } 
     // ... 
    } 
} 

Lý do tại sao tôi nghĩ tình trạng này "lý tưởng" thực hiện chủ yếu là để không để buộc tất cả các Ts để thực hiện IConvertibleFrom <> .

+2

điều gì lý tưởng về việc triển khai phản ứng với lỗi thời gian lập trình với ngoại lệ thời gian chạy? –

+1

nếu bạn có một loạt các loại đã chuyển đổi từ chuỗi và bạn muốn sử dụng chúng trong một lớp/phương pháp mới theo cách tôi mô tả trừu tượng, đây sẽ là cách ít tốn kém nhất để triển khai nó. Nó sẽ là một loại sơn để chỉnh sửa mọi loại và thực hiện giao diện mới. –

Trả lời

3

Cho rằng bạn muốn chuyển đổi từ kiểu String kín, bạn có thể bỏ qua nullable có thể, đấm bốc, tài liệu tham khảo và rõ ràng chuyển đổi. Chỉ có op_Implicit() đủ điều kiện. Một cách tiếp cận chung chung hơn được cung cấp bởi lớp System.Linq.Expressions.Expression:

using System.Linq.Expressions; 
... 
    public static T DoSomethingWith(string s) 
    { 
     var expr = Expression.Constant(s); 
     var convert = Expression.Convert(expr, typeof(T)); 
     return (T)convert.Method.Invoke(null, new object[] { s }); 
    } 

Hãy coi chừng chi phí của Phản ánh.

+0

Điều này hoạt động, cảm ơn! –

-1

Tại sao bạn không thể làm điều gì đó như thế này?

public class MyClass<T> where T : string 
{ 
    public T DoSomethingWith(string s) 
    { 
     // ... 
    } 
} 

Bằng cách này bạn có thể kiểm tra xem s là mui trần để T trong mã DoSomethingWith. Từ đó bạn có thể ném ngoại lệ nếu nó không thể, hoặc làm đúc, nếu nó có thể

+1

Tại sao nên sử dụng generics nếu bạn khai báo rõ ràng rằng kiểu generic phải là một chuỗi? –

+0

d, tôi tuyên bố 'T' như phải được bắt nguồn từ chuỗi, điều này không giống như nói nó phải là chuỗi. – Graviton

+1

Không, tôi có các loại của riêng mình có thể được chuyển đổi từ một chuỗi. (PS: bạn không thể kế thừa từ chuỗi). –

-1
if(!typeof(T).IsAssignableFrom(typeof(String))) { 
    throw new Exception(); 
} 
+1

Thật không may là không hoạt động với các toán tử ngầm hoặc rõ ràng được khai báo trên kiểu đối số. –

+0

hmm, tôi không chắc chắn tôi sẽ theo dõi bạn trong thư trả lời của bạn. đoạn mã đó sẽ ném một ngoại lệ nếu 'T' là một int, nhưng không phải nếu nó là một chuỗi hoặc một đối tượng. đó không phải là những gì bạn đang theo sau? –

+0

Tôi đã thử nghiệm nó với lớp MyClass {public static implicit operator MyClass (chuỗi s) {return new MyClass(); }} và typeof (MyClass) .IsAssignableFrom (typeof (string)) trả về false. Tôi giả sử bạn mong đợi nó trở lại sự thật ... –

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