2013-05-28 11 views
9

Tôi đã không ngủ trong một thời gian vì vậy điều này có thể dễ dàng hơn tôi nghĩ.Đối tượng đúc thành kiểu chung

Tôi có một lớp chung đó là nhiều hay ít này:

public class Reference<T> where T : APIResource //<- APIResource is abstract btw 
{ 
    private T _value = null; 
    public T value 
    { 
     get { return _value; } 
    } 
} 

Ở những nơi khác, trong một phương pháp tùy chỉnh serialize, ai đó đang đi qua trong một object mà thực sự là một thể hiện của Reference<(something)>. Tôi chỉ đơn giản muốn bỏ qua cho "giá trị" tài sản mà mỗi đối tượng Reference<> có, vì vậy tôi muốn đi:

string serialize(object o) 
{ 
    return base.serialize(((Reference<>) o).value); 
} 

Tất nhiên, cuộc sống không phải là đơn giản bởi vì như trình biên dịch đặt nó:

using the generic type "Reference<T>" requires 1 type arguments

Tôi có thể làm những gì tôi muốn làm?

Trả lời

14

Bạn có thể tạo một giao diện chung hiệp biến với bất động sản:

interface IReference<out T> where T : ApiResource { 
    T Value { get; } 
} 

Sau đó bạn có thể cast IReference<Anything>-IReference<object> hoặc IReference<ApiResource>.

+0

Tôi biết hoàn toàn không có gì về giao diện chung biến đổi nên tôi thực sự vui vì tôi đã chuyển sang SO. Tôi đã phải sửa đổi lớp chung cho phù hợp: 'public class Reference : IReference trong đó T: APIResource {...}'. Điều này cho phép tôi truy xuất thuộc tính Value với '((IReference ) o) .Value' – Alain

3

Câu trả lời là hoàn hảo. Tôi chỉ muốn mở rộng nó một chút:

Đôi khi có những tình huống, nơi bạn không thể thay thế lớp học bằng giao diện. Chỉ trong những trường hợp mà bạn có thể muốn sử dụng dynamic tính năng, do đó bạn có thể gọi value tài sản:

string serialize(object o) 
{ 
    if(typeof(Reference<>) == o.GetType().GetGenericTypeDefinition()) 
     return base.serialize(((dynamic)o).value); 

    //in your case you will throw InvalidCastException 
    throw new ArgumentException("not a Reference<>", "o"); 
} 

Đây chỉ là một lựa chọn và tôi đề nghị sử dụng nó rất cẩn thận.

+0

Cảm ơn bạn đã thay thế. Rõ ràng đây là một phương sách cuối cùng, nhưng rất quan trọng để có ở đây trong trường hợp một người nào đó không thể sửa đổi các lớp chung chung trong câu hỏi. – Alain

1

Dont quên kiểm tra xem loại generic của nó hay không ---> o.GetType(). IsGenericType, trước khi

sử dụng o.GetType(). GetGenericTypeDefinition() khác nó ném ngoại lệ ..