.NET中值和引用类型之间的差异

时间:2010-12-23 14:31:29

标签: .net types garbage-collection

我在理解.net框架中引用和值类型之间的区别时遇到了一个小问题。你可能会说这是每个程序员应该知道的基本差异,而且我相信会知道这种不同之处,但有时会发生在某些书籍中对这个问题有不同的看法。

我知道.NET是一个托管环境,垃圾收集器存在并运行。数据和结构存储在两个主要位置:托管堆栈

托管堆应该充当所有指向驻留在堆栈中的实际数据的指针的容器。这就是我所知道的以及Dino Esposito关于.NET的书中解释的内容(谈论vb.net)。 是这样吗?或者有些事情不正确?

我还有另一个问题...... 或者更好,我需要确认我的想法...

当我在c#

中写这样的东西时
string mystring = "Hello World!";

我认为CLR在堆栈中创建一个字符串数据,并在堆中创建指向该数据的指针。 如果我这样做:

mynamespace.someprintfunction(mystring);

CLR检索“Hello World!”会发生什么?通过查看mystring(堆中的指针到堆栈中的数据)。

此外,鉴于字符串是不可变的,如果我这样做:

string mystring2 = "Hello World!";

CLR不会在堆中创建新的指针mystring2和“Hello World!”的记录。在堆栈中,但它使用预先存在的“Hello World!”由mystring指出并创建一个新指针。 结果是mystring和mystring2指向堆栈中的相同位置。

2 个答案:

答案 0 :(得分:3)

你混淆了堆和堆栈。如果创建引用类型的实例,通常会在堆上分配此类的内存​​,并在堆栈上获得指向该数据的引用/指针。

关于值和引用类型之间的区别,有人说值类型存储在堆栈上的堆栈和引用类型上,但这并不总是正确的(同样,它是CLR的实现细节,在大多数情况下也无关紧要为用户)。

最重要的区别是,值类型按值传递 (在分配时将整个数据复制到另一个变量中),引用类型按引用(您仅复制对原始数据的引用)。

所以当你执行int x = 5; int y = x;时,你正在复制x的值。 x和y不是指相同的数据。 另一方面,如果对引用类型的实例执行相同操作,则两个变量都引用同一对象。

答案 1 :(得分:1)

并非所有所谓的“真实数据”都存在于堆栈中 例如:

public static void Main()
{
   int a = 5;
   int[] arr = new int[20];
}

a是一个值类型,它的4个字节在堆栈上,而arr是指向堆分配内存的指针,arr本身(指针)在堆栈上但是实际的数组数据(即使它是一个整数的数组)正在堆上分配。

修改
关于你的第二个问题 1.字符串文字保存在特殊位置,因此两个字符串变量将指向同一个对象 当你执行string mystring = "Hello World!";时,mystring将指向字符串文字,并且在调用方法时,指向字符串的指针将作为方法参数被推送到堆栈。