C# 装箱,拆箱,向上转型,向下转型
2017-07-21 14:23
253 查看
c#中,数据类型分为值类型和引用类型,装箱和拆箱属于值类型和引用类型间的转换操作,一下简要介绍装箱和拆箱:
装箱:值类型向引用类型转换时发生, 当 CLR 对值类型进行装箱时,会将该值包装到 System.Object 内部,再将后者存储在托管堆上。 以下为装箱操作实例:
此语句的结果是在堆栈上创建对象引用 o,而在堆上则引用 int 类型的值。 该值是赋给变量 i 的值类型值的一个副本。 装箱时一个隐式转换,但显示装箱也是可以的。
拆箱:从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。拆箱操作包括:
(1)检查对象实例,以确保它是给定值类型的装箱值。
(2)将该值从实例复制到值类型变量中
参照:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/types/boxing-and-unboxing
要在运行时成功取消装箱值类型,被取消装箱的项必须是对一个对象的引用,且该对象是先前通过装箱该值类型的实例创建的。 尝试取消装箱 null 会导致 NullReferenceException。 尝试取消装箱对不兼容值类型的引用会导致 InvalidCastException。
向上转型:将子类对象转为父类对象,父类对象可以是接口。转化后的对象具有父类的所有方法,当该方法被子类重写时,具有的是被子类重写过的方法。若父类对象是接口或者抽象类,调用方法时,自动找到子类同名方法,执行子类同名方法。向上转换时安全的
向下转型:把父类对象转为子类对象,转化后的子类对象,跟一般的继承子类对象一样。具有子类所有方法(包括重写方法)+父类所有方法(被重写的方法,按重写的算。)向下转型属于不安全转型,使用转型对象时,需要先判断转型是否成功。其转型的约束条件为:该对象进行过向上转型,并把它转换为原来的类。
装箱:值类型向引用类型转换时发生, 当 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(); //打印出“嗅觉相当不错!”,即子类方法可用。
相关文章推荐
- C#向上转型与向下转型
- java向上转型和向下转型
- C#的类型转换(2)之装箱拆箱和Nullable
- 【C#】装箱与拆箱
- C#基础知识系列二(值类型和引用类型、可空类型、堆和栈、装箱和拆箱)
- C# 向下遍历删除子目录和子文件 及 向上遍历空的父目录
- C#“装箱”(boxing)与“拆箱”(unboxing)
- 栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#] - [IT]
- 向上转型,向下转型
- Java入门记(二):向上转型与向下转型
- C#的装箱与拆箱
- 【面试题研究3】c#中装箱和拆箱的概念
- 装箱和拆箱(什么是装箱和拆箱) C#基础
- C#中的装箱和拆箱(boxing and unboxing)
- 重写重载,向上向下转型
- C# 装箱和拆箱
- java向上转型与向下转型
- Java中的向上转型与向下转型
- c# 装箱与拆箱 小概念 大问题
- 面向对象中的多态,对象的向上转型和向下转型