我发现了这个典型的编译错误:



我熟悉 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 在 IDctQueryIQuery 中是逆变的。但是一旦您将 IDct 添加为类型参数,对 K 的要求现在是协变的。所以你需要改为
interface IDctQuery<out K> : IQuery<IDct<K>>
{
}

假设您有两个类, DogAnimalDog 是一个 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/

10-14 07:49