C# 用c语言编写上下转换表达式#
我最近一直在研究c#中的向上投射和向下投射。我知道向上转换是指从派生类到基类的转换。然而,当我看到一个向上投射的实际例子(如下所示)时,我感到困惑C# 用c语言编写上下转换表达式#,c#,downcast,upcasting,C#,Downcast,Upcasting,我最近一直在研究c#中的向上投射和向下投射。我知道向上转换是指从派生类到基类的转换。然而,当我看到一个向上投射的实际例子(如下所示)时,我感到困惑 public class Shape { ... } public class Circle : Shape { ... } Circle circle = new Circle(); Shape shape = new Shape(); // Converting an object into its base class reference
public class Shape
{
...
}
public class Circle : Shape
{
...
}
Circle circle = new Circle();
Shape shape = new Shape();
// Converting an object into its base class reference
shape = circle
如果我们将圆转换为它的基类引用,它不应该是这样的吗
circle = shape
如果听起来太业余的话,对不起。这是因为我总是看到以下格式的表达式:
int x = 3; // means assign 3 to variable x.
所以我很困惑为什么圆圈在右手边而不是左手边。请告知。把我当作初学者。 你在例子中所做的事情也可以写成以下内容:
Circle circle = new Circle();
Shape shape = (Shape)circle; //Casting the object to the base type
class Shape {}
class Circle : Shape {}
class Triangle : Shape {}
因此,您正在将Circle
类型的对象强制转换为Shape
类型的对象。
在代码中,这是“自动”完成的,因为您正在将值分配给类型为Shape
的新变量
这稍微解释了转换/基类:(旁白:这称为向上转换,因为传统上,绘制类图时,基类在派生类的上方物理显示。)
现在,当您这样做时:
shape = circle; // shape->(instance of Circle)
您正在将圆
引用指定给形状
引用,以便在指定后,引用形状
将引用圆
这很好,因为您可以使用形状
执行所有操作,也可以使用圆
执行所有操作
但是,如果您:
circle = shape; // circle->(instance of Shape)
您正在将形状
参照指定给圆
参照。您不能这样做,因为(如果可能的话)您将能够访问圆形形状中不存在的功能
例如,假设Circle.Radius
存在,但Shape.Radius
不存在
如果允许您将圆
参考点指向形状
如果您尝试访问圆.半径
,会发生什么情况?答案是:会发生未定义的行为,因为形状.半径不存在。否
问题是:形状
不是圆
,而是圆
是形状
这意味着圆
始终可以放置在需要形状
的位置,但当您需要圆
时,您不能将任何形状
放入其位置,因为它也可能是三角形
这就是为什么需要显式地强制转换它(使用(Type)变量
或变量作为Type
)
基本上,我们假设如下:
Circle circle = new Circle();
Shape shape = (Shape)circle; //Casting the object to the base type
class Shape {}
class Circle : Shape {}
class Triangle : Shape {}
现在,我们还有一个三角形
,使我们能够更好地进行布局:
Circle c = new Circle();
Triangle t = c; // Impossible due to Circle not being a Triangle
Shape s = c; // Possible because a Circle is a Shape
Triangle t2 = s; // Impossible because Shape may be a Triangle or any other derived class
若你们知道集合,你们就可以很容易地理解为什么“shape=circle”是可以的,“circle=shape”是不可以的
想想这个
A是字母表中的一个字符
所以我们可以说
public class A : Alphabet
{
}
正如我们所知
字母表也是
public class Alphabet
{
}
如果我们画一个图表,它可以是这样的
┌───────── Alphabet ───────┐
│ A B C D E ... a b c ... z│
└──────────────────────────┘
我们可以说z是字母表,但我们不能说Alplabet是z,因为字母表包含的不仅仅是z
让我们看看圆和形状
圆包含形状信息,并添加了更多变量。(可能没有,但可以更改。)
所以我们可以说圆是一组形状
我们可以根据形状修改圆。我们还可以初始化圆
但若你们做“Shape=Circle”,那个么圆中的一些东西就无法初始化
它返回错误。我将尝试解释:
变量shape
包含对shape
类型的对象的引用
当您编写Shape Shape=newshape()时代码>变量shape
将包含对新shape
对象的引用
通过写入shape=circle
重新指定shape
时,它包含对另一个对象的引用。对象圆
的类型为圆
,但由于圆继承了形状
,因此可以执行此赋值;将圆
隐式转换为键入形状
进行此转换的另一种可能更清晰的方法是进行显式转换:
Circle circle = new Circle();
Shape circleAsShape = (Shape)circle;
向上转换意味着将对象的类型更改为派生较少的基类(Circle
对象更改为Sape
)
向下浇铸在另一个方向工作,例如从形状
浇铸到圆形
派生类型较多的变量可以很容易地分配给派生类型较少的变量,因为这里隐式地进行了向上转换,因为圆
也是一个形状
。这就是为什么派生类型较多的值可以分配给派生类型较少的VARABLE
它不以另一种方式工作,因为形状
是通用的,我们不知道它是否是圆
。因此,当您尝试向下转换时,需要显式指定它:
// this won't work
Shape shape = new Shape();
Circle c = (Circle)shape;
// this will
Shape shape = new Circle();
// we know we have Circle object so we can downcast
Circle c = (Circle)shape;
相关/类似问题:,以及。所有这些参考资料都解释了铸造是如何工作的。