大家都知道要学好 .NET,深入了解值类型和引用类型是必不可少的。在这里我给大家简单分析一下它们内存分配的区别和联系。
在分析之前,我们先行构造出一个最简单的类引用类型:
public class MyClass
{
}
局部变量的声明
在我们使用类型时,代码里面必然少不了变量的声明,我们先看一下方法内的局部变量的声明,请看如下代码:
private static void Main()
{
int i;
MyClass mc;
i = 5;
mc = new MyClass();
}
当一个局部变量声明之后,就会在栈的内存中分配一块内存给这个变量,至于这块内存多大,里面存放什么东西,就要看这个变量是值类型还是引用类型了。
l 值类型
如果是值类型,为变量分配这块内存的大小就是值类型定义的大小,存放值类型自身的值(内容)。比如,对于上面的整型变量 i,这块内存的大小就是 4个字节(一个 int型定义的大小),如果执行 i = 5;这行代码,则这块内存的内容就是 5(如图 -1)。
对于任何值类型,无论是读取还是写入操作,可以一步到位,因为值类型变量本身所占的内存就存放着值引用类型
如果是引用类型,为变量分配的这块内存的大小,就是一个内存指针(实例引用、对象引用)的大小(在 32位系统上为 4字节,在 64位系统上为 8字节)。因为所有引用类型的实例(对象、值)都是创建在堆上的,而这个为变量分配的内存就存放变量对应在堆上的实例(对象、值)的内存首地址(内存指针),也叫实例(对象)的引用。以图形化的方式展现仿佛是变量有一条线指向着它在堆中的实例(有如图 -2),而如果变量的类型还没有被实例化,则为零地址( null、空引用)。
以下为执行 mc = new MyClass ();代码后,内存中的示例:
由图 -2可知,变量 mc中存放的是 MyClass实例(对象)的对象引用,如果需要访问 mc实例,系统需要首先从 mc变量中得到实例的引用(在堆中的地址),然后用这个引用(地址)找到堆中的实例,再进行访问。需要至少 2步操作才可以完成实例访问。
类型赋值