C#的Boxing/Unboxing解析
来源:互联网 发布:python可视化运维 编辑:程序博客网 时间:2024/05/01 19:40
相比较C++,C#中的值类型和引用类型很简单:所有的基本类型、结构(struct)和String属于值类型,其它类型(其实也只剩下class了)都属于引用类型。那么值类型和引用类型有什么区别呢?
值类型在赋值操作(“=”操作,函数参数,函数返回等)的时候,会把所有成员变量拷贝一遍给目标实例。
引用类型在赋值操作的时候,只是把实例的内存中的地址赋值给目标实例。
那么这两者有什么区别呢?
那就是效率了:
引用类型的赋值只要传递一个内存地址,传递的数据量就是一个32(64位操作系统是64)位整数。
值类型需要传递该类型所包含的所有数据。
比如:
struct Point
{
public int x;
public int y;
}
那Point类型的实例在赋值的时候,要传递的数据量是两个整数。
如果数据量更大的结构,每次赋值的时候都要传递一遍所有的成员,那么总的程序运行期内,传递的数据量就非常可观了。
怎么解决这种效率问题呢?
有两种方法:
1 使用ref关键字。
2 就是用所谓的Boxing/Unboxing了。
首先,Boxing/Unboxing是针对值类型数据而言的。对引用类型来说,它本身就是引用类型,所以不存在Boxing/Unboxing的概念。
其次,Boxing的操作就是把值类型的数据赋值到一个object的引用类型实例中,这个过程是值赋值的过程(就是所以数据都copy一遍)。
如:
Point p = new Point{x=10, y=11};
Object o = p;
这个变量o就是Boxing之后的引用类型了。记住一点,boxing之后,变量o就跟p无关了,它们是两个不同类型的变量,指向不同的内存地址。
最后,Unboxing的操作是把这个object的引用类型实例,以值传递的方式赋值给目标对象。
如:
Point p2 = (Point)o;
unboxing之后,p2跟o就无关了,它们是两个不同类型的变量,指向不同的内存地址。
也就是说,Boxing/Unboxing的最大用途就是用于数据传递。
理解Boxing/Unboxing还要与class的类型向父类/子类转换的操作区别开来(面向对象语言的继承机制)。
将一个class的实例转换成它的父类或子类类型,这是类的继承机制。这种转换其实只是把实例的类型信息变了下,实例对应的数据,内存地址都没变动。转换前后的实例都是指向同一块内存。
但我们可以把Boxing/Unboxing和class继承机制统一起来,用一句话来概括就是:引用进,引用出;值进,值出。
值类型在赋值操作(“=”操作,函数参数,函数返回等)的时候,会把所有成员变量拷贝一遍给目标实例。
引用类型在赋值操作的时候,只是把实例的内存中的地址赋值给目标实例。
那么这两者有什么区别呢?
那就是效率了:
引用类型的赋值只要传递一个内存地址,传递的数据量就是一个32(64位操作系统是64)位整数。
值类型需要传递该类型所包含的所有数据。
比如:
struct Point
{
public int x;
public int y;
}
那Point类型的实例在赋值的时候,要传递的数据量是两个整数。
如果数据量更大的结构,每次赋值的时候都要传递一遍所有的成员,那么总的程序运行期内,传递的数据量就非常可观了。
怎么解决这种效率问题呢?
有两种方法:
1 使用ref关键字。
2 就是用所谓的Boxing/Unboxing了。
首先,Boxing/Unboxing是针对值类型数据而言的。对引用类型来说,它本身就是引用类型,所以不存在Boxing/Unboxing的概念。
其次,Boxing的操作就是把值类型的数据赋值到一个object的引用类型实例中,这个过程是值赋值的过程(就是所以数据都copy一遍)。
如:
Point p = new Point{x=10, y=11};
Object o = p;
这个变量o就是Boxing之后的引用类型了。记住一点,boxing之后,变量o就跟p无关了,它们是两个不同类型的变量,指向不同的内存地址。
最后,Unboxing的操作是把这个object的引用类型实例,以值传递的方式赋值给目标对象。
如:
Point p2 = (Point)o;
unboxing之后,p2跟o就无关了,它们是两个不同类型的变量,指向不同的内存地址。
也就是说,Boxing/Unboxing的最大用途就是用于数据传递。
理解Boxing/Unboxing还要与class的类型向父类/子类转换的操作区别开来(面向对象语言的继承机制)。
将一个class的实例转换成它的父类或子类类型,这是类的继承机制。这种转换其实只是把实例的类型信息变了下,实例对应的数据,内存地址都没变动。转换前后的实例都是指向同一块内存。
但我们可以把Boxing/Unboxing和class继承机制统一起来,用一句话来概括就是:引用进,引用出;值进,值出。
- C#的Boxing/Unboxing解析
- Boxing and unboxing in C#
- boxing, unboxing
- C#中的"装箱"(boxing)与"拆箱"(unboxing)
- C#中的装箱(boxing)拆箱(unboxing)
- C#中的装箱(boxing)拆箱(unboxing) (续)
- C#中的装箱(boxing)拆箱(unboxing)
- C#中的"装箱"(boxing)与"拆箱"(unboxing)
- C#的基本类型的封箱(boxing)与拆箱(unboxing)
- C#中装箱和拆箱的作用 the effection of boxing and unboxing
- C#中的“装箱”(boxing)与“拆箱”(unboxing)
- Effective C#之17:Minimize Boxing and Unboxing.
- C#装箱(Boxing)和拆箱(Unboxing)
- C#中的装箱(Boxing)和拆箱(Unboxing)
- C#装箱和拆箱(Boxing 和 UnBoxing)
- 11.3 Boxing and unboxing
- 关于Boxing和Unboxing
- Boxing and Unboxing
- 使用DBMS_STATS重放性能问题
- 跨子域页面间的 JavaScript
- VB中通过oo4o进行Oracle数据库操作-Select
- 国际:IT 职场--对商业技能的需求与日俱增
- String和StringBuilder区别
- C#的Boxing/Unboxing解析
- Socket Error Code
- eclipse快捷键大全
- HIBERNATE是什么
- 1.2.6 不匹配的代价
- 初用DWR,Demo折腾了好久!
- C++的反射开源代码
- 转:ASP.NET中的路径问题总结
- 一些假如你相信,就会毁掉你一生的谎言