被值类型,引用类型,装箱,拆箱这几个概念困惑了很长时间,一直不是特别理解。刚好今天不是很忙,拿出点时间专门研究一下。
首先研究什么是值类型,什么是引用类型,两种有什么不同?
CLR支持两种类型:值类型和引用类型。.net框架参考文档已经明确指定了那种类型是值类型,那种类型是引用类型,如下图:

值类型和引用类型最根本的区别是:两者在内存中的分配位置不同,值类型(Value Type)的实例分配在线程的堆栈上,而引用类型(Reference Type)的实例总是从托管堆上分配内存。
值类型和引用类型的比较
看下面一段代码
protected void Page_Load(object sender, EventArgs e)
{
ValueTypeDemo();
}
class SomeRef
{
public int x;
}
struct SomeVal
{
public int x;
}
public void ValueTypeDemo()
{
SomeRef r1 = new SomeRef();
SomeVal v1 = new SomeVal();
r1.x = 5;
v1.x = 5;
Response.Write(r1.x);
Response.Write(v1.x);
SomeRef r2 = r1;
SomeVal v2 = v1;
r1.x = 8;
v1.x = 9;
Response.Write(r2.x);
Response.Write(v2.x);
}
注:上面代码来自《.net框架程序设计中文版》
在上面的代码中,SomeVal被声明为结构体,在C#中,声明为结构体的类型被认为是值类型,而用Class声明的类型是引用类型。下图是引用类型和值类型内存布局的差别。
ValueTypeDemo前半部分执行后的情况 ValueTypeDemo完全执行后的情况
程序执行结果:5 5 8 5
从上面的例子可以看出,两个或多个引用类型可以指向托管堆中的同一个对象,这样对一个变量的操作可能影响到其它变量引用的对象,而每个值类型变量都有一份自己的数据拷贝,不存在这个问题。但是正因为如此,值类型的实例不适合被频繁用于方法的传递,也不适合作为方法的结果频繁返回。
最后,因为值类型的实例没有分配在托管堆上,所以一旦定义该类型的实例方法不在处于活动状态,为他们分配的控件就会立即释放。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12639172/viewspace-548712/
,如需转载,请注明出处,否则将追究法律责任。