考虑我们有三个类,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..
}
}
一件事是,Circle
和 Text
都是 Shape
,但是您不能将 Circle
转换为文本
。这是因为这两个类都扩展了 Shape
类并添加了不同的功能/属性。
例如:一辆汽车
和一辆自行车
共享它们相同的底座Vihicle
(用于运送人或 cargo 的东西,尤其是在陆地上),但是 Bike
用鞍座扩展 Vihicle
而 Car
用例如扩展 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/