在 C# 中转换基本数组的派生成员

Casting a derived member of a base array in c#

我有一个基础 class Shape 和两个派生的 classes CircleRectangle。现在我已经编写了从 RectangleCircle 的显式转换,反之亦然。它们没有多大意义,但这不是我现在的意思。我创建了新的 RectangleCircle 实例,并希望通过强制转换将 Rectangle 分配给 Circle。这按预期工作。

但是如果我有一个 Shape 类型的数组,其中填充了 Rectangles,并且想要转换数组的成员,它会抛出一个 System.InvalidCastException。因为我已经写了明确的演员表,所以我不知道为什么这是不可能的。

Shape[] arr = new Shape[5];

Circle c1 = new Circle(1, 2, 3);
Circle c2 = new Circle(4, 5, 6);
Rectangle r1 = new Rectangle(7, 8);
Rectangle r2 = new Rectangle(9, 10);
Shape c3 = new Circle(3, 9, 13);

arr[0] = c1;
arr[1] = c2;
arr[2] = r1;
arr[3] = r2;
arr[4] = c3;


Console.WriteLine(r1.GetType());
Console.WriteLine(arr[2].GetType()); // both evalute to Rectangle

Circle r3 = (Circle)r1;             // compiles
Circle r4 = (Circle)arr[2];         // Unhandled Exception

好的,正如 Ondrej 指出的那样,这是从 Shape 到 Circle 的 Cast,这是不允许的。然而,ingvar 指出这是可行的:

Circle r5 = (Circle)((Rectangle)arr[2]);    
Rectangle r6 = (Rectangle)((Circle)arr[0]);

而这不是

Circle r5 = (Circle)arr[2];   
Rectangle r6 = (Rectangle)arr[0];

感谢您的帮助!

Circle r4 = (Circle)arr[2];

编译器无法应用显式转换,因为它无法静态确定 arr[2] 实际上存储的是 Rectangle。对于编译器,它是 Shape,因此 (Circle)arr[2] 是从 ShapeCircle 的转换。

您将 Shape 数组的元素直接转换为 Circle,这是不可能的,因为实际上您的对象是 Rectangle。尝试显式转换:

Circle r4 = (Circle)((Rectangle)arr[2]);