2013-05-28 97 views
9

我還沒有睡過一陣子,所以這可能比我想象的要容易。將對象投射到通用類型

我有一個泛型類或多或少這樣的:

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

其他地方,在一個自定義的序列化方法,有人正在傳遞一個object,實際上是Reference<(something)>一個實例。我只是想跳到每個Reference<>對象具有「值」屬性,所以我想去的地方:

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

當然,生活不是那麼簡單的,因爲當編譯器所言:

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

我該怎麼做我想做的事?

回答

14

您可以創建一個屬性協通用接口:

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

然後,您可以施放IReference<Anything>IReference<object>IReference<ApiResource>

+0

我對協變通用接口一無所知,所以我很高興我轉向了SO。我必須相應地修改泛型類:'public class Reference :IReference where T:APIResource {...}'。這允許我通過'((IReference )o).Value' – Alain

3

SLaks答案是完美的。我只是想擴大一點:

有時候,你不能用接口替換class。 只有在情況下,您可能需要使用dynamic功能,讓您可以撥打value屬性:

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"); 
} 

這只不過是另一種選擇,我建議非常仔細地使用它。

+0

檢索Value屬性感謝您的選擇。很明顯,這是最後的手段,但在這裏遇到某些人無法修改相關類屬時非常重要。 – Alain

1

不要忘了查看其是否泛型類型或不---> o.GetType()。IsGenericType,使用o.GetType()。GetGenericTypeDefinition(

)否則拋出異常之前..