【问题标题】:Casting a derived member of a base array in c#在 C# 中强制转换基数组的派生成员
【发布时间】:2019-08-22 15:04:24
【问题描述】:

我有一个基类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


    【解决方案1】:
    Circle r4 = (Circle)arr[2];
    

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

    【讨论】:

    • 这似乎合乎逻辑,但我无法编写从 Shape 到 Circle 的显式转换。所以我的方法是不可能的?
    • 我建议您更新您的问题,包括显式转换在内的所有声明并提供minimal reproducible example
    • 感谢您的帮助,我想我现在明白了。由于程序知道 arr[2] 是一个 Rectangle,我可以将它从 Shape 转换为 Rectangle,然后从 Rectangle 转换为 Circle。虽然第一个演员不是真正的演员,但它只是有效,因为 arr[2] 已经是一个 Rectangle
    • 就是这样。无论如何,请随时发布更全面的示例,我们可以进一步讨论。
    【解决方案2】:

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

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

    【讨论】:

    • 这行得通,但是如果我不能投射到圆形,为什么我可以投射到矩形?这些都是 Shape 的派生类,还是我遗漏了什么?
    • C# 没有向下转换。除非编译器知道此元素类型,否则您不能直接将基类型的对象转换为子类型的对象。在您的情况下,编译器知道您的元素是Rectangle,因此它允许将其转换为Rectangle
    猜你喜欢
    • 2015-05-29
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 2015-03-27
    • 2019-11-13
    • 1970-01-01
    • 2016-10-10
    • 2012-02-04
    相关资源
    最近更新 更多