2011-12-06 9 views
8

私はいくつかの助言/助けが必要ですが、私はもう木から木材を見ることはできません。C#キャスティングジェネリック(共分散と反動?)

ジェネリックを使用していくつかのインターフェイスを実装する、まっすぐ進む一連のクラスです。

それから私は、例えば、コンクリートの型をキャストしようとしている:

MyGenericObject<SomeObject> _obj; 

IMyGenericObject<ISomeObject> _genObj = (IMyGenericObject<ISomeObject>)_obj; 

//無効な私は、なぜこのwouldn」共変性と反変性についてのいくつかの記事を読んで、あまりにも明確ではありませんしました

をキャスト可能なのか、それをどうやって得るのか?


ので、この例では:あなたが活動プロパティを取得して設定することができない、ので

public interface IMyObject<in T> where T : IBaseObject 
{ 
    T Activity { get; set; } 
} 

は.... ...


を動作しないでしょう。この例では

、私が行うために必要な:誰か、そして助けをすべてに感謝を助け

public interface IMyObject<out T> where T : IBaseObject 
    { 
     T Activity { get; } 
    } 

希望!

+0

あなたのインターフェースの定義を表示してください。 –

答えて

9

共分散(out)パラメータを持つとしてインターフェイスを宣言する場合にのみ行うことができます。パラメータが共変に使用されている場合にのみ実行できます。

たとえば、インターフェイスIMyGenericObject<T>Tパラメータを使用するメソッドがある場合、パラメータを共変変数として宣言できなくなります。逆に、Tを返すメソッドがあると、パラメータを反例として宣言することができなくなります。 SLaksの答えにあなたのコメントに応えて

EDIT

、私はエリックリペットは、これまでコとcontravarianceに書かれたすべてのものを繰り返すように誘惑しています。それはFileInfoIList<object>に渡すための法的なので

あなたはIList<object>IList<string>をキャストすることはできませんが、合格するための法的ではありません。(最近https://stackoverflow.com/a/8380213/385844)SOでhttp://blogs.msdn.com/b/ericlippert/archive/tags/Covariance+and+Contravariance/とも彼の答えを参照してください

を要約しますそれはIList<string>になります。

それはIList<string>からアイテムを取得し、文字列参照に割り当てる法的ですが、IList<object>は、文字列に割り当てることができないのFileInfoを、含まれている場合がありますので、あなたは、IList<string>IList<object>をキャストすることはできません参照。

EDIT 2

あなたがアドバイスを求めているので、それは共同と反変の部分にあなたのインターフェイスを分割することも可能です。リストの例を続行するには、これはあなたがコンテキストに応じて、covariantlyまたはcontravariantlyクラスを使用することができ、これらのインタフェース

public interface ICovariantList<out T> 
{ 
    T this[int index] { get; } 
    //... 
} 

public interface IContravariantList<in T> 
{ 
    T this[int index] { set; } 
    void Add(T item); 
    //... 
} 

public class SomeList<T> : ICovariantList<T>, IContravariantList<T> 
{ 
    //... 
} 

を持つことができます。

+0

、おかげさまで助けを! – sambomartin

+0

@sambomartinよろしくお願いします。 EDIT 2のいくつかのアドバイス。 – phoog

+0

ありがとう、私はちょっと終わりにセッターを必要としませんでしたが、私はそれをsussed ...しかし、私は次回のために知っている! – sambomartin

4

インターフェイスに共変(out)汎用パラメータがあると宣言する必要があります。

+2

共変が「出る」です。反変は「in」です。ニーモニック: "o"は共変量と外を表します。 contravariantとのための "n"。 – phoog

+0

、ありがとう。次の問題は、コンパイラが次のように報告していることです。 "エラー1無効な分散:型パラメータ 'xxxは、' xxxが共変量で不変である必要があります。私が読んだことから、インターフェイスを読み込み/不変にする必要があります。私はIMyGenericInterfaceのプロパティを持っていますSomeObject SomeObjectInstance {get; set;}任意のアイデア? – sambomartin

+0

@sambomartin:分散の仕組みを理解する必要があります。書き込み可能なバリアントプロパティは、本質的に型セーフではありません。 – SLaks