c# - 为什么我们需要在 C# 中进行向上转型和向下转型?

标签 c# downcast upcasting

考虑我们有三个类,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
    {

    }
}

我们都知道向上转型总是成功的,并且我们从子类引用创建对基类的引用

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

向下转型可能会抛出 InvalidCastException 例如

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

我感到困惑的是,我们可能需要向上/向下转换和反对的情况/案例是什么?

最佳答案

通常,您对存储在列表中的对象使用向上转型。 (共享基类型,甚至可以使用 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,但是您不能将 Circle 转换为文本。这是因为这两个类都扩展了 Shape 类并添加了不同的功能/属性。

例如:一辆汽车和一辆自行车共享它们相同的底座Vihicle (用于运送人或 cargo 的东西,尤其是在陆地上),但是 Bike 用鞍座扩展 VihicleCar 用例如扩展 vihicle,马达。因此它们不能相互“转换”,但都可以看作是一个 Vihicle


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

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

“真实世界”示例:

如果你有一个窗口,它上面有很多控件。像标签/按钮/ ListView /等。所有这些控件都存储在它们的基本类型的集合中。

例如 WPF 控件:所有子控件(在 FrameWorkElement 中) 都存储在 UIElementCollection 中。因此,作为子控件添加的所有控件必须都派生自 UIElement

当您迭代所有子控件时,(UIElement's) 并搜索例如标签时,您必须检查它的类型:

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

此循环会将所有标签(在此范围内)更改为“您好!”。

关于c# - 为什么我们需要在 C# 中进行向上转型和向下转型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39743777/

相关文章:

c# - Asp.net MVC 路由不匹配某些文件扩展名

java - 如何在Java中向下转换数组?(多态)

c# - 如何使用 SWIG 生成的接口(interface)在 C# 中正确向下转换?

java - java中的隐式向上转型和显式向下转型

c# - 如何在接口(interface)中将方法设为私有(private)?

c# - 我在这个 C# 代码中使用 Math.Pow(a,b) 函数有多不对?

c# - Amazon Web Services 解决方案不会在 Release模式下构建

swift - 无法修改函数体内的函数参数

c++ - 如果不在纯虚拟基类中创建显式函数,就无法完成复制构造吗?

c++ - 类的转换(向上转换)