C# 6.0 in a Nutshell by Joseph Albahari and Ben Albahari (O’Reilly).
Copyright 2016 Joseph Albahari and Ben Albahari, 978-1-491-92706-9.
第 123-124 页关于类型协变的陈述:
Arrays, for historical reasons, array types support covariance. This means that B[] can be cast to A[] if B subclasses A (and both are reference types).
For example:
Bear[] bears = new Bear[3];
Animal[] animals = bears; // OK
The downside of this reusability is that element assignments can fail at runtime:
animals[0] = new Camel(); // Runtime error
这种错误背后的原因是什么? 如果将 Bear 的实例分配给 Animal 的实例,将抛出运行时错误?我不明白为什么它应该(通过允许这样的分配,编译器需要负责声明“好吧,我会让你用这个对象做动物可以做的一切。”因为 Bear 是一种动物,这会导致没有任何问题。
我创建了自己的场景来测试以上内容:
public class X
{
public int Num { get; set; }
public void Method_1()
{
Console.WriteLine("X");
}
public virtual void Method_2()
{
Console.WriteLine(Num);
}
}
public class Y : X
{
public Y()
{
Num = 1000;
}
}
X[] arrayX = new X[] { new X { Num = 1000 }, new X { Num = 999 }, new X { Num = 51762 } };
Y[] arrayY = new Y[] { new Y { Num = 5 }, new Y { Num = 6 }, new Y { Num = 7 } };
X x = new X { Num = 1000 };
Y y = new Y { Num = 50 };
x = y;
arrayX = arrayY;
arrayX[2] = new Y { Num = 1 };
// will print 5,6,1 - no runtime errors faced
foreach (var e in arrayX)
Console.WriteLine(e.Num);
我相信上面的代码片段模仿了书中的示例 - 但对于我的代码片段,没有运行时错误。
我错过了什么?如书中所述,animals[0] = new Camel();
应该如何引发运行时错误?
最佳答案
What is the reason behind such error?
因为它试图将 Camel
存储到运行时类型为 Bear[]
的数组中。 Bear[]
类型的数组只能存储对Bear
实例或子类的引用。 Animal[]
的编译时类型只表示它可能能够存储一个Camel
引用,并且你得到的任何引用 < em>out 数组肯定是 Animal
实例或子类。
你的例子是不同的。当我们删除所有属性等(不相关的)时,您将获得:
X[] arrayX = new Y[3];
arrayX[2] = new Y();
没关系 - 将对 Y
对象的引用存储在执行时类型为 Y[]
的数组中。没问题。
要演示与书中相同的问题,您需要第三堂课:
class Z : X {}
X[] arrayX = new Z[3];
arrayX[2] = new Y(); // Bang - can't store a Y reference in a Z[]
关于c# - 类型协方差运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38569201/