我想我真的需要是变化的一个简单的解释 - 逆变和协方差 - 在C#泛型的情况下,我已经找到here和here:
错误消息并没有真正使我说,但现在我会总结:
逆变
通用类,当然是一个类的模板而不是类定义,可以使用逆向使用的关键字。甲逆变类允许从基类的实例分配到一个派生类实例即边境牧羊犬=犬
public interface AllowAssignmentsFromBaseToDerived<in T>
协方差
泛型类可以使用出关键字进行协变。甲协变类允许从派生类实例分配到基类的实例,即狗=边境牧羊犬
public interface AllowAssignmentsFromDerivedToBase<out T>
方差被支承用于数组类型,因为C#1.0和委托类型,因为C#2.0,以及因为C#通用类型参数4.0。
很高兴能有更多的回复来覆盖我已经错过的更多观点,仍然感觉有点不知情。
更多信息从here解禁:
如何创建变型通用接口和委托自己?
out关键字将类型参数标记为协变,并且 关键字将其标记为逆变。到 两个最重要的规则要记住:
您可以标记一个泛型类型参数的协变如果只是 作为方法的返回类型,而不是作为一种形式化方法 参数。
反之亦然,你可以,如果它 只是用来作为一种形式化方法的参数,而不是用作 方法的返回类型标记类型逆变。
interface IVariant<out R, in A>
{
// These methods satisfy the rules.
R GetR();
void SetA(A sampleArg);
R GetRSetA(A sampleArg);
// And these don’t.
// A GetA();
// void SetR(R sampleArg);
// A GetASetR(R sampleArg);
}
此外,如果扩展一个变种通用接口是默认不变。您需要根据需要指定In或Out。
最后,我的解释将是远远不够的尝试Eric Lippert's blog
因为'IList'是不变的(或者更具体地说,它不是协)在其类型参数。如果该方法的声明返回类型是,例如,“IEnumerable>'',您可以返回'List >'。 –
换句话说:问题是关于什么可以传递到列表的方法有冲突的规则。 'IList>'声明你可以用任何'IEnumerable '调用'Add',但是'List >'说它必须是一个HashSet。但是,您可以创建一个'List >',并将HashSets添加到它。 –
nmclean