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

问题描述 投票:0回答:2

我有一个基类Shape与两个派生类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指出这是一个从形状到圆形的铸造,这是不允许的。然而,ingvar指出这是有效的:

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

这没有

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

谢谢你的帮助!

c# arrays class casting derived
2个回答
0
投票

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

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

1
投票
Circle r4 = (Circle)arr[2];

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

© www.soinside.com 2019 - 2024. All rights reserved.