covariance and contravariance 上有一些很棒的资源在 StackOverflow 上,但我似乎误解了逆变的基本原理。我希望这个示例能够工作:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
A a = new B();
B b = new A();
}
}
public class A
{
int id { get; set; }
}
public class B : A
{
}
将 a 设置为 B 可行,这是协方差,但将 b 设置为新的 A 会失败并出现编译错误。即使进行显式转换仍然会在编译时产生错误。有没有办法做到这一点,还是我完全误解了逆变?
最佳答案
do I just completely misunderstand contravariance?
是的。您完全完全误解了“协变”和“逆变”的含义。您将它们与作业兼容性 混淆了。
这是一个极其常见的错误。这两个概念是相关的,但它们完全不同。
赋值兼容性是一种类型的表达式可以存储在另一种类型的变量中的属性。
Covariance 是从类型到类型的映射保持方向分配兼容性的属性。如果 Giraffe 与 Animal 兼容,这意味着 IEnumerable<Giraffe>
作业是否与 IEnumerable<Animal>
兼容然后是 IEnumerable<T>
映射是协变的。
有关此主题的更多详细信息,请参阅我的文章:
Setting a to B works, which is covariance
是的,它有效。 “a”与 B 赋值兼容。不是“协方差”,因为没有变化。没有从类型到类型的映射来保留赋值“a = B”中使用的赋值兼容性方向;没有什么是通用的。
but setting b to a new A fails with a compile error.
正确。
Is there a way to do this ?
没有。而不是“A”和“B”,称它们为动物和长颈鹿。每个长颈鹿都是一个动物,所以如果一个变量可以容纳一个动物,那么它就可以容纳一个长颈鹿。如果您尝试采用另一种方式,则无法将 Animal 放入 Giraffe 类型的变量中。动物实际上可能是老虎。为什么允许将 Tiger 放入 Giraffe 类型的变量中?
关于c# - 类的隐式逆变 - 简单的失败示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4876499/