2013-05-28 10 views
9

私はしばらく寝ていないので、これはおそらく私が思うより簡単です。オブジェクトをジェネリック型にキャスト

私はこれより以下の汎用クラスがあります。他の場所で

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

は、カスタムのSerializeメソッドでは、誰かが実際にReference<(something)>のインスタンスであるobjectに渡しています。私は単純にすべての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<object>またはIReference<ApiResource>IReference<Anything>をキャストすることができます。

+0

私は共変のジェネリックインターフェースについては何も知りませんでしたので、私は本当に嬉しく思いました。それに応じてジェネリッククラスを修正しなければなりません: 'public class Reference :IReference T:APIResource {...}'。これにより、私は '((IReference )o).Value'を使ってValueプロパティを取得することができます。 – Alain

3

SLaks回答は完璧です。私はそれをちょっと拡張したいだけです:

クラスをインターフェイスで置き換えることはできません。 のみあなたがvalueプロパティを呼び出すことができるようにあなたは、dynamic機能を使用したい場合があり、その場合には:

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

ありがとうございます。明らかにこれは最後の手段ですが、誰かが問題のジェネリッククラスを変更できない場合に備えておくことが非常に重要です。 – Alain

1

いけないそのジェネリック型か---> o.GetType o.GetTypeを(使用して

の前に()。IsGenericType、)かどうかをチェックするのを忘れ。GetGenericTypeDefinition()そうでなければ例外をスローします。..

関連する問題