看了CODEPROJECT上篇讲BOXING的文章,觉得不错,故翻译并修改理顺之,对beginner(比如本人)是个不错的选择
首先,C#(JAVA也是),将类型分为值类型(value type)和引用类型(reference type).
VALUE TYPE
值类型的数据放在堆栈中的,用来存放固定长度的数据,如INT。每个程序在运行时都有自己的堆栈,其他程序不能访问。所有的value type都是继承自system.valuetype.常见的如简单类型的数(INT,DOUBLE。。)和复合类型(枚举,结构)。
引用类型:
引用类型的数放在堆(HEAP)里,存放可变长度的数据,没有预先指定大小,,如数组,接口,委托,类等,都属于引用类型。
下面举例子说明:
比如, System.ValueType r = 5;,这样的写法是成立的,自动匹配认为r的类型是int32,
如果用Console.WriteLine(r.GetType()) ;,可以清楚看到R的类型;
什么是BOXING(装箱)呢?
boxing,就是将值类型转变为引用类型的过程,比如
Int32 x = 10;
object o = x ; //隐式转换
Console.WriteLine("The Object o = {0}",o); //输出10
//-----------------------------------------------------------
Int32 x = 10;
object o = (object) x; // 显式转换
Console.WriteLine("The object o = {0}",o); // prints out 10
上面的例子可以看到,一个int32类型的值10,通过object o=x;进行隐式的BOXING,转变为引用类型,而通过object o=(object)x,这样进行的是显式转换,结果一样。注意,隐式转换是编译器自动进行的。
什么是UNBOXING(拆箱)呢?
比如:
Int32 x = 5;
object o = x; // 隐式BOXING
x = o; // 隐式UNBOXING
就是将引用类型转换为值类型。
当然,上面也可以这样写,用显式unboxing:
Int32 x = 5;
object o = x;
x = (Int32)o;
要特别注意的是,在unboxing中,如果象下面那样
Int32 x = 5;
Int64 y = 0;
object o = x;
y = (Int64)o;
Console.WriteLine("y={0}",y);
这样编译起来,会出现System.InvalidCastException异常,因为x的值在boxing为32位值后,必须unboxing为32位.当然,可以在unboxing为32位后,再强制转换为64位,如
y = (Int64)(Int32)o;
还要特别注意的是,在unboxing时,要确保得到的值变量有足够的空间存储所有的字节,比如
long a=123323456;
object c=(object)a;
int d=(int)c;
会出现错误,因为64位的值A先BOXING为引用类型,存储在堆上,再unboxing为32位值int,则因为D没空间存储值而出错
首先,C#(JAVA也是),将类型分为值类型(value type)和引用类型(reference type).
VALUE TYPE
值类型的数据放在堆栈中的,用来存放固定长度的数据,如INT。每个程序在运行时都有自己的堆栈,其他程序不能访问。所有的value type都是继承自system.valuetype.常见的如简单类型的数(INT,DOUBLE。。)和复合类型(枚举,结构)。
引用类型:
引用类型的数放在堆(HEAP)里,存放可变长度的数据,没有预先指定大小,,如数组,接口,委托,类等,都属于引用类型。
下面举例子说明:
比如, System.ValueType r = 5;,这样的写法是成立的,自动匹配认为r的类型是int32,
如果用Console.WriteLine(r.GetType()) ;,可以清楚看到R的类型;
什么是BOXING(装箱)呢?
boxing,就是将值类型转变为引用类型的过程,比如
Int32 x = 10;
object o = x ; //隐式转换
Console.WriteLine("The Object o = {0}",o); //输出10
//-----------------------------------------------------------
Int32 x = 10;
object o = (object) x; // 显式转换
Console.WriteLine("The object o = {0}",o); // prints out 10
上面的例子可以看到,一个int32类型的值10,通过object o=x;进行隐式的BOXING,转变为引用类型,而通过object o=(object)x,这样进行的是显式转换,结果一样。注意,隐式转换是编译器自动进行的。
什么是UNBOXING(拆箱)呢?
比如:
Int32 x = 5;
object o = x; // 隐式BOXING
x = o; // 隐式UNBOXING
就是将引用类型转换为值类型。
当然,上面也可以这样写,用显式unboxing:
Int32 x = 5;
object o = x;
x = (Int32)o;
要特别注意的是,在unboxing中,如果象下面那样
Int32 x = 5;
Int64 y = 0;
object o = x;
y = (Int64)o;
Console.WriteLine("y={0}",y);
这样编译起来,会出现System.InvalidCastException异常,因为x的值在boxing为32位值后,必须unboxing为32位.当然,可以在unboxing为32位后,再强制转换为64位,如
y = (Int64)(Int32)o;
还要特别注意的是,在unboxing时,要确保得到的值变量有足够的空间存储所有的字节,比如
long a=123323456;
object c=(object)a;
int d=(int)c;
会出现错误,因为64位的值A先BOXING为引用类型,存储在堆上,再unboxing为32位值int,则因为D没空间存储值而出错