Contravariance/Covariance,为什么不能投这个?

Contravariance/Covariance, why can't cast this?

面对现实吧,在泛型中使用协变和逆变时,我仍然难以理解约束。

我想知道,为什么我有这个:

public interface IFasterListCov<out T>
{}

public interface IFasterListCon<in T>
{}

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

第三次施法失败:

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>

在您调用 QueryNodes<MyNode> 的情况下,为了让您的最后一次转换获得非空值,您使用 _nodesDB[type] 获得的实际实例必须是 FasterList<MyNode>FasterList<SomeOtherMostlyCompatibleNode>.

还不够好

运行时对类型非常严格,它跟踪所涉及的所有内容的实际运行时类型,数据类型相似或只有 MyNode 个对象填充是不够的您的 FasterList<SomeOtherMostlyCompatibleNode>,或其他任何内容。如果类型不完全它们应该是什么,您需要进行某种编程转换,而不仅仅是转换。

MyType : IMyType 不会使 Generic<IMyType>Generic<MyType> 有任何关联。

在您的特定情况下,nodesT 很可能是 FasterList<Node>,而 不是 FasterList<INode>.

请注意,当您可以指定 in/out 时,此转换适用于支持变体 (co/contra) 的接口,正如您在成功转换为接口时看到的那样。有关详细信息,请参阅许多问题之一 - 即 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?