gpt4 book ai didi

c# - 一般约束类中的协方差误差

转载 作者:太空狗 更新时间:2023-10-30 00:22:48 25 4
gpt4 key购买 nike

我有一个带有协变类型参数的接口(interface):

interface I<out T>
{
T Value { get; }
}

另外,我有一个非泛型基类和另一个从它派生的基类:

class Base
{
}

class Derived : Base
{
}

协方差表示 I<Derived>可以分配给 I<Base> , 事实上 I<Base> ib = default(I<Derived>);编译得很好。

但是,这种行为显然随着具有继承约束的泛型参数而改变:

class Foo<TDerived, TBase>
where TDerived : TBase
{
void Bar()
{
I<Base> ib = default(I<Derived>); // Compiles fine
I<TBase> itb = default(I<TDerived>); // Compiler error: Cannot implicitly convert type 'I<TDerived>' to 'I<TBase>'. An explicit conversion exists (are you missing a cast?)
}
}

为什么这两个案例不一样对待?

最佳答案

Covariance says that an I<Derived> can be assigned to an I<Base>

正确。

Why are these two cases not treated the same?

您的陈述过于笼统了。你的逻辑似乎是这样的:

  • 协方差表示 I<Derived>可以分配给 I<Base>
  • DerivedBase是具有父类(super class)型-子类型关系的任意类型。
  • 因此,协变适用于任何具有父类(super class)型-子类型关系的类型。
  • 因此,协变适用于具有这种关系的泛型类型参数。

虽然看似合理,但该逻辑链是错误的。正确的逻辑链是:

  • 协方差表示 I<Derived>可以分配给 I<Base>
  • DerivedBase是具有父类(super class)-子类关系的任意引用类型。
  • 因此,协变适用于具有父类(super class)-子类关系的任何引用类型。
  • 因此,协变适用于被限制为具有此类关系的引用类型的泛型类型参数。

在你的例子中,一个人完全有权制作 Foo<int, object> .自 I<int>无法转换为 I<object> , 编译器拒绝来自 I<TDerived> 的转换至 I<TBase> .请记住,编译器必须证明泛型方法适用于所有可能的结构,而不仅仅是您创建的结构。泛型不是模板。

错误信息可以更清楚,我同意。对于糟糕的体验,我深表歉意。改进这个错误在我的 list 上,但我从来没有做到。

你应该输入 class对您的泛型类型参数进行约束,然后它将按您预期的方式工作。

关于c# - 一般约束类中的协方差误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50935140/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com