黑马程序员技术交流社区

标题: C#中的值类型与引用类型 [打印本页]

作者: 康子龙    时间: 2012-10-20 03:58
标题: C#中的值类型与引用类型

对于值类型和引用类型,我们单从概念上来看,其区别只是值类型直接存储其值,而引用类型存储的是值的引用。

     这两种类型在内存中存储的表现为:值类型存储在堆栈中,而引用类型存储在托管堆上。这种存储位置上的不同相应的,也会有不同的影响。

举例:


int j,i;
i=20;
j=i;
这里由于int是值类型的,所以上面的代码在内存中实际上开辟了两块空间存储的值20。 但考虑下面的代码。这段代码假定已经定义了一个类Test,Test是一个引用类型,它有一个int类型的成员变量Value:
Test x,y;
x=new Test();
x.Value=30;
y=x;
Console.WriteLine(y.Value);
y.Value=50;
Console.WriteLine(x.Value);
要理解的重要一点是在执行这段代码后,只有一个Test对象。x和y都指向包含该对象的内存位置。因为x和y是引用类型的变量,声明这两个变量只保留了一个引用——而不会实例化给定类型的对象。两种情况下都不会真正创建对象。要创建对象,就必须使用new关键字,如上所示。因为x和y引用同一个对象,所以对x的修改会影响y,反之亦然。因此上面的代码会显示30和50。

如果变量是一个引用,就可以把其值设置为null,表示它不引用任何对象:
y=null;
在C#中,基本数据类型如bool,long都是值类型。如果声明一个long类型的变量,并给它赋予另一个long变量的值,在内存中就会有两个bool值,而它俩之间也没有必然联系,修改之中一个不会影响另一个。 大多数更复杂的C#数据类型,包括我们自己声明的类都是引用类型。其分配在堆中,生存期可跨多个函数调用。CLR执行一种精细的算法,来跟踪哪些引用变量仍是可以访问的,哪些引用变量已经不能访问了。CLR会定期删除不能访问的对象,把他们占用的内存返回给操作系统。这是通过垃圾回收器实现的。
把基本类型(如int和bool)规定为值类型,而把包含许多字段的较大类型规定为引用类型,C#这样设计是为了得到最佳性能。如果要把自己的类型定义为值类型,就应把它声明为一个结构。



作者: 颜晋南    时间: 2012-10-20 07:50
  对于引用类型嵌套值类型,以及值类型嵌套引用类型的情况下,内存分配可以根据以下两条规律来判断:
1) 引用类型始终部署在托管堆上;  
2)  值类型总是分配在它声明的地方:作为字段时,跟随其所属的对象存储;作为局部变量时,存储在栈上.
作者: 康子龙    时间: 2012-10-20 10:12
颜晋南 发表于 2012-10-20 07:50
对于引用类型嵌套值类型,以及值类型嵌套引用类型的情况下,内存分配可以根据以下两条规律来判断:
1) 引 ...

当作为在堆中的对象的一部分时应该是存储为内联吧




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2