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

我最近一直在研究c#中的向上投射和向下投射。我知道向上转换是指从派生类到基类的转换。然而,当我看到一个向上投射的实际例子(如下所示)时,我感到困惑

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;
相关/类似问题:,以及。所有这些参考资料都解释了铸造是如何工作的。