所以我试图理解 c# 中的向上转换和向下转换。
我的问题是,这张图是正确的还是我还遗漏了什么?如果它不正确,我在哪里可以找到正确表示这个概念的图表?
任何帮助是极大的赞赏。
编辑:首先,我为造成的混乱道歉,我意识到图表不是很清楚,而且我在向下转换时犯了一个错误(其中 circle2 只能访问字符串颜色,它应该可以访问所有属性)。我将尝试更好地解释我试图代表的内容。
因此,这是与之配套的代码:
public class Shape
{
public int Width {get;set;}
public int Height {get;set;}
public int X {get;set;}
public int Y {get;set;}
public void Draw()
{
//do something
}
}
public class Circle : Shape
{
public string Colour {get;set;}
}
public class Program
{
public static void Main(string[] args)
{
//Up-casting
Circle circle = new Circle(); //object is created
Shape shape = circle; // shape point to circle object
//Down-casting
Circle circle2 = (Circle)shape;
}
}
Run Code Online (Sandbox Code Playgroud)
你不需要任何图表,只要把基本事实记下来,一切就会变得一清二楚。
上下转换以order 为前提,所以让我们先弄清楚:
在典型的类型层次结构中,我们有以下内容:
Animal -> Vertebrate -> Mammal -> Feline -> Cat
Run Code Online (Sandbox Code Playgroud)
较高或更一般的类型是Animal
,而最低或更具体的类型是Cat
;因此,顺序是类型的“一般性”。
向上转换是转换为更一般的类型,向下转换是转换为更具体的类型:
Animal animal = new Cat();
var feline = (Feline)animal;
好的,但是这两个“演员表”真的都在发生吗?当我们向下或向上投射时,对象会发生什么变化?答案很简单;没有!根本没有对对象进行任何更改。
两种强制转换都是引用转换,它们是身份保留的;这意味着转换之前和转换之后的对象是完全相同的对象。顾名思义,您唯一要更改的是指向对象的引用类型;变量animal
和cat
。
这样做很明显:ReferenceEquals(animal, feline);
which will return true
。
注意向上转换总是隐式的,因为它总是安全的;aCat
总是 aFeline
总是 aMammal
等等。另一方面,向下转换必须是明确的,因为它们不能保证是安全的:
Animal animal = new Dog();
Feline feline = animal; //unsafe, can not implicitly do the conversion
Run Code Online (Sandbox Code Playgroud)
编译器要求您显式执行强制转换,这是一种告诉编译器“我知道我在做什么,animal
是一个Feline
,相信我。”的方式。当然,编译器只会部分信任您,并且仍会提供运行时保护以确保强制转换是可能的,否则会抛出运行时异常。在上面的代码中,转换显然会失败,你会得到一个运行时错误。
请注意,所有这些仅适用于Reference Types。根据定义,值类型没有引用转换,因为您无法获得对值类型的引用。这是值类型中不允许类型变化的原因之一;没有身份保留转换,类型变化中唯一允许的转换。
归档时间: |
|
查看次数: |
2087 次 |
最近记录: |