- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如果一个类满足以派生类作为类型参数的协变接口(interface),为什么这不足以满足以基类作为类型参数的相同接口(interface)的约束?
给定以下代码
public interface ICovariantInterface<out T>
{
T Value { get; }
}
public class Base { public int Value { get; set; } }
public class Sub : Base { public int OtherValue { get; set; } }
public class A : ICovariantInterface<Sub>
{
Sub _sub = new Sub { Value = 1, OtherValue = 2 };
public Sub Value { get { return _sub; } }
}
public class B : A
{
ICovariantInterface<Base> MeAsInterface { get { return this; } }
}
public interface OtherInterface : ICovariantInterface<Base>
{ int ThirdValue { get; } }
public class C : A, OtherInterface
{
ICovariantInterface<Base> MeAsInterface { get { return this; } }
public int ThirdValue { get { return 2; } }
}
B 类工作正常 - 因为 A 满足类型参数为 Sub 的协变接口(interface) ICovariantInterface,它可以立即转换为类型参数为 Base 的相同接口(interface) - 但 C 编译失败,出现错误
'CovarianceTest.C' does not implement interface member 'CovarianceTest.ICovariantInterface.Value'. 'CovarianceTest.A.Value' cannot implement 'CovarianceTest.ICovariantInterface.Value' because it does not have the matching return type of 'CovarianceTest.Base'.
当C可以立即转换为约束中指定的接口(interface)时,C怎么会不满足约束呢?
这个问题让我很难充分利用协方差提供的可能性。
最佳答案
协变(和逆变)为消费类型建立规则,类型参数标记为out
(或in
),如果你拥有特定类型的实例,作为消费者,您可以使用某些隐式转换。
在您的示例中,B
在您允许的强制转换发生的时间点。
但在您的 C
示例中,您正在尝试实现 一个接口(interface)。协变和逆变在这里不适用 - 如果接口(interface)声明方法返回 T
,那么实现必须提供一个方法,该方法返回 完全 替换 的类型>T
.
关于c# - 为什么接口(interface)的协方差在约束中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48228566/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!