您的位置:首页 > 编程语言 > C#

C# 装箱,拆箱,向上转型,向下转型

2017-07-21 14:23 253 查看
c#中,数据类型分为值类型和引用类型,装箱和拆箱属于值类型和引用类型间的转换操作,一下简要介绍装箱和拆箱:

装箱:值类型向引用类型转换时发生, 当 CLR 对值类型进行装箱时,会将该值包装到 System.Object 内部,再将后者存储在托管堆上。 以下为装箱操作实例:

int i = 123;
// The following line boxes i.
object o = i;


此语句的结果是在堆栈上创建对象引用 o,而在堆上则引用 int 类型的值。 该值是赋给变量 i 的值类型值的一个副本。 装箱时一个隐式转换,但显示装箱也是可以的。

拆箱:从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。拆箱操作包括:

(1)检查对象实例,以确保它是给定值类型的装箱值。

(2)将该值从实例复制到值类型变量中

int i = 123;      // a value type
object o = i;     // boxing
int j = (int)o;   // unboxing


参照:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/types/boxing-and-unboxing

要在运行时成功取消装箱值类型,被取消装箱的项必须是对一个对象的引用,且该对象是先前通过装箱该值类型的实例创建的。 尝试取消装箱 null 会导致 NullReferenceException。 尝试取消装箱对不兼容值类型的引用会导致 InvalidCastException。

向上转型:将子类对象转为父类对象,父类对象可以是接口。转化后的对象具有父类的所有方法,当该方法被子类重写时,具有的是被子类重写过的方法。若父类对象是接口或者抽象类,调用方法时,自动找到子类同名方法,执行子类同名方法。向上转换时安全的

class Animal
{
public void call() { Console.WriteLine("无声的叫唤"); }
}
class Dog : Animal
{
// new的作用是隐藏父类的同名方法
public new void call() { Console.WriteLine("叫声:汪~汪~汪~"); }
public void smell() { Console.WriteLine("嗅觉相当不错!"); }
}
Animal animal = new Dog();             //向上转型①

animal.call();   //打印出“无声的叫唤”,调用的是父类本身的call方法。

// animal.smell();        //出错,不存在此方法。


向下转型:把父类对象转为子类对象,转化后的子类对象,跟一般的继承子类对象一样。具有子类所有方法(包括重写方法)+父类所有方法(被重写的方法,按重写的算。)向下转型属于不安全转型,使用转型对象时,需要先判断转型是否成功。其转型的约束条件为:该对象进行过向上转型,并把它转换为原来的类。

Dog dog = animal as Dog;
//Dog dog = (Dog)animal; 不安全操作,
//如果转换不成功将会报错
//向下转型
dog.call();
//打印出“叫声:汪~汪~汪~”,即调用的是Dog类的call方法。
dog.smell();
//打印出“嗅觉相当不错!”,即子类方法可用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  转型 装箱-拆箱