我发现了这个典型的编译错误:
我熟悉 Covariance and Contravariance in C# 的基础知识,但我仍然不明白为什么它是错误的:
interface IQuery<in D>
{
}
interface IDct<in K>
{
}
// error here ↓
interface IDctQuery<in K> : IQuery<IDct<K>>
{
}
请解释我
UPD
有趣的是,这段代码是完全有效的:
interface IQuery<out D>
{
}
interface IDct<out K>
{
}
interface IDctQuery<out K> : IQuery<IDct<K>>
{
}
最佳答案
正在发生的事情是,通过使用逆变类型作为另一个逆变类型的类型参数,这会反转类型参数 K 的方向。听起来令人困惑,但这工作正常:
interface IDctQuery<in K> : IQuery<K>
{
}
因为 K 在
IDctQuery
和 IQuery
中是逆变的。但是一旦您将 IDct
添加为类型参数,对 K 的要求现在是协变的。所以你需要改为interface IDctQuery<out K> : IQuery<IDct<K>>
{
}
假设您有两个类,
Dog
和 Animal
。 Dog
是一个 Animal
,协变接口(interface)保留了这种关系。因此 IEnumerable<Dog>
可以分配给 IEnumerable<Animal>
。逆变接口(interface)逆转了这种关系。因此可以将
IQuery<Animal>
分配给 IQuery<Dog>
并且可以将 IDct<Animal>
分配给 IDct<Dog>
。您的接口(interface)声明:
interface IDctQuery<in K> : IQuery<IDct<K>>
{
}
说可以将
IDctQuery<Animal>
分配给 IDctQuery<Dog>
,因此可以将 IQuery<IDct<Animal>>
分配给 IQuery<IDct<Dog>>
并且因为 IQuery
是逆变的,这意味着 IDct<Dog>
可以分配给 IDct<Animal>
这不是正确的,因为 IDict
可以被分配,因为 IDct<Animal>
可以被分配IDct<Dog>
但不是相反。关于c# - 复杂泛型中的无效方差,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23516269/