2016-05-19 13 views
0

私はまだ、ジェネリックで共分散と反分散を使うときに、制約を理解するのが難しいです。Contravariance/Covariance、なぜこれをキャストできませんか?

私はこれがあれば、なぜ私は、不思議:

public interface IFasterListCov<out T> 
{} 

public interface IFasterListCon<in T> 
{} 

public class FasterList<T> : IList<T>, IFasterListCov<T>, IFasterListCon<T> 

を第三のキャストが失敗した:あなたがあなたの最後のキャストが取得するためには、QueryNodes<MyNode>を呼んでいるシナリオでは

public void QueryNodes<T>() where T:INode 
{ 
    //somehow I can convert IFasterListCon<INode> to IFasterListCon<T> 
    IFasterListCon<INode> nodes = (IFasterListCon<INode>)_nodesDB[type]; 
    //I guess this works because _nodesDB[type] is indeed a FasterList<T> object 
    //note: I am wrong, I can cast whatever INode implementation, not just T, which made me very confused :P 
    IFasterListCon<T> nodesT = (IFasterListCon<T>)nodes; 
    //I can't cast IFasterListCon<T> back to FasterList<T> 
    FasterList<T> nodeI = nodesT as FasterList<T>; //null 
} 

Dictionary<Type, IFasterListCov<INode>> _nodesDB; 

to be clear _nodesDB[type] is a FasterList<T> declared through IFasterListCov<INode> 
+0

nodesT' 'の_actual_タイプは何ですか?基礎となる型が互換性がある場合にのみ機能する_downcast_を実行しています。 –

+0

あなたはTとは何ですか? TはINodeを実装しなければなりません(constrainはwhere節にあります)... ah ok _nodesDBには全てのFasterListが含まれています sebas

+1

'FasterList 'は 'FasterList 'ではありません。 – Lee

答えて

1

MyType : IMyTypeGeneric<IMyType>Generic<MyType>は何らかの形で関連していません。あなたの特定のケースで

nodesTないFasterList<INode>FasterList<Node>である可能性が高いです。

in/outと指定することができる場合、この変換は、分散(共/逆)をサポートするインターフェイスで動作することに注意してください。詳細については、多くの質問の1つ(Generic Class Covariance)をご覧ください。

優れた答えはまた、約List共同変動がある - C# variance problem: Assigning List<Derived> as List<Base>List<Derived>List<Base>が、互いの間にキャストすることができないことを示しています

List<Giraffes> giraffes = new List<Giraffes>(); 
List<Animals> animals = new List<Animals>() {new Lion()}; 

(giraffes as List<Animals>).Add(new Lion()); // What? Lion added to Girafes 
Giraffe g = (animals as List<Giraffes>)[0] ; // What? Lion here? 
+0

NodeがINodeを実装していても、FasterList はFasterList ではありませんか? – sebas

+0

はい - Giraffesに関するすばらしい説明を参照してください - http://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase(具体的なクラスについて話しますが、インターフェイス/クラスペア) –

+0

ok私は言語がFasterList をIFasterListCon にキャストされたいと思っていると理解していますが、この場合は逆です。私は一般化ではなく、専門化にキャストしています。 – sebas

1

をnull以外の値の場合、_nodesDB[type]で取得する実際のインスタンスはFasterList<MyNode>である必要があります。それがFasterList<SomeOtherMostlyCompatibleNode>であることは十分ではありません。

ランタイムはタイプに関して非常に厳しく、関連するすべての実際のランタイムタイプを把握しています。データタイプが似ているだけで十分ではありません。MyNode個のオブジェクトにFasterList<SomeOtherMostlyCompatibleNode>、 else。タイプがの場合は、正確にはでなければなりません。キャストだけでなく、何らかのプログラマチックな変換を行う必要があります。

+0

私は明確ではありませんでした... FasterListノードにはMyNode要素が含まれています。だからFasterList .Add(MyNode)...擬似コードが意味を成すならば。 – sebas

関連する問題