Skip to content
On this page

引用类型

引用类型包括数组、类和字符串。关于应用程序执行时存储值的方式,引用类型与值类型的处理方式不同。

在此练习中,我们将了解引用类型与值类型的不同之处,以及如何使用 new 运算符将变量与计算机内存中的值相关联。

引用类型与值类型有何不同

值类型变量会将其值直接存储在名为堆栈的存储区域中。堆栈是为 CPU 上当前运行的代码分配的内存(也称为堆栈帧或激活帧)。堆栈帧执行完毕后,堆栈中的值将被删除。

引用类型变量会将其值存储在名为堆的单独内存区域中。堆是一个内存区域,由操作系统上运行的多个应用程序同时共享。 .NET 运行时与操作系统进行通信以确定可用的内存地址,并请求可存储该值的地址。 .NET 运行时存储值,然后将内存地址返回给变量。当代码使用变量时,.NET 运行时会无缝查找变量中存储的地址,并检索其中存储的值。

让我们编写一些代码来更清楚地说明这些概念。

定义引用类型变量

以下代码定义可保存 int 阵列类型值的变量:

csharp
int[] data;

此时,data 仅仅是一个变量,可以存储引用,或者说堆中某个值的内存地址。由于它不指向内存地址,因此称为空引用。

使用 new 关键字创建 int 阵列的实例

修改步骤 2 中的代码,使用以下代码创建和分配 int 阵列的新实例:

csharp
int[] data;
data = new int[3];

new 关键字指示 .NET 运行时创建 int 阵列的实例,然后与操作系统协调,将该实例存储在内存中。 .NET 运行时编译并返回新 int 阵列的内存地址。最后,内存地址存储在变量数据中。 int 阵列的元素默认为值 0,因此它是 int 的默认值。

修改代码示例,以一行代码执行两项操作

步骤 3 中的两行代码一般会缩短为一行代码,以同时声明变量并创建 int 阵列的新实例。请将步骤 3 中的代码修改为以下代码:

csharp
int[] data = new int[3];

虽然没有输出可供查看,但好的是此练习更清楚地说明了 C# 语法与使用引用类型的过程步骤之间的关系。

为什么 C# 的 string 数据类型不一样?

string 数据类型也是引用类型。你可能会奇怪为什么我们在声明字符串时不使用 new 操作符。这仅仅是因为 C# 设计者想要提供一种便利。由于 string 数据类型使用非常频繁,因此我们可以使用以下格式:

csharp
string shortenedString = "Hello World!";
Console.WriteLine(shortenedString);

但在后台,系统会创建 System.String 的新实例,并将其初始化为“Hello World!”。

备注

语言设计者创建的简化快捷方式有时又称为“糖衣语法”。你可能会在文章、视频和演示文稿中看到对这一说法的使用。

概括

  • 值类型可以存储较小的值,并存储在堆栈中。引用类型可以存储大额的值,引用类型的新实例使用 new 操作符创建。引用类型变量存储堆中存储的实际值的引用(内存地址)。
  • 引用类型包括数组、字符串和类。