为什么在C#中我们需要Upcasting & Downcasting?

问题描述 投票:1回答:1

考虑到我们有三个类,Shape是基类,另外两个类Circle和Text继承自基类(Shape)。

形状.cs

namespace ObjectOriented
{
    public class Shape
    {
        public int Height { get; set; }
        public int Width { get; set; }
        public int X { get; set; }
        public int Y { get; set; }

        public void Draw()
        {

        }
    }
}

文本.cs

using System;

namespace ObjectOriented
{
    public class Text : Shape
    {
        public string FontType { get; set; }
        public int FontSize { get; set; }

        public void Weirdo()
        {
            Console.WriteLine("Weird stuff");
        }

    }
}

圆形.cs

namespace ObjectOriented
{
    public class Circle : Shape
    {

    }
}

我们都知道Upcasting总是成功的,我们从一个子类引用中创建一个基类的引用。

Text txt = new Text();
Shape shape = txt //upcast

和下投可抛出和 InvalidCastException 比如

Text txt = new Text();
Shape shape = txt; //upcast
Circle c = (Circle)shape; //DownCast InvalidCastException

我所困惑的是,什么是什么?状况案例 我们可能需要更新cast和object?

c# downcast upcasting
1个回答
5
投票

通常你对存储在例如列表中的对象使用upcasting。(共享基础类型,甚至 Object 可以使用)

List<Shape> shapes = new List<Shape>();

shapes.Add((Shape)new Text());    // <-- the upcast is done automatically
shapes.Add(new Circle());

在下料的时候,你需要检查是否是正确的类型。

foreach(Shape shape in shapes)
{
    if(shape is Circle)
    {
        Circle circle = (Circle)shape;
        // do something..
    }

}

有一点是: CircleText 都是 Shape但你不能施放 CircleText. 这是因为这两个类都在扩展 Shape 类,并添加不同的functionityproperties。

例如 A Car 和a Bike 同根同源 Vihicle 担子但是,a Bike 扩展了 Vihicle 鞍前马后 Car 例如,用电机来扩展车辆。因此,它们不能相互 "铸造",但两者都可以被看作是一个整体。Vihicle.


有一些有用的扩展方法,可以处理类型检查。

foreach(Circle circle in shapes.OfType<Circle>())
{
    // only shapes of type Circle are iterated.
}

"真实世界 "的例子:

如果你有一个Window,上面有很多控件。比如LabelsButtonsListViewsetc。所有这些控件都存储在其基础类型的集合中。

例如WPF控件。所有的子控件 (在FrameWorkElement中) 储存在 UIElementCollection. 所以所有的控件都被添加为子控件 必须 得自 UIElement.

当你在迭代所有的子控件时。(UIElement's) 并搜索一个标签,你必须检查它的类型。

foreach(UIElement element in this.Children)
{
    if(element is Label)
    {
        Label myLabel = (Label)element;
        myLabel.Content = "Hi there!";
    }
}

这个循环将改变所有标签 (在此范围内) 到'你好!'。

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