C# 中数组是值类型还是引用类型?
在 C# 中,数组是 引用类型。无论是 int[]
、string[]
还是用户自定义类型的数组,数组本身存储在托管堆(Heap)中,变量实际上保存的是数组对象的引用。
特点分析
-
数组是引用类型
- 数组变量本身存储的是数组对象的引用。
- 数组数据存储在托管堆中,而数组变量指向堆中的数据。
-
数组的元素可以是值类型或引用类型
- 如果数组的元素是值类型,例如
int
或double
,它们存储在数组的连续内存块中。 - 如果数组的元素是引用类型,例如
string
或自定义对象,则数组存储的是这些引用的地址,实际数据存储在堆中。
- 如果数组的元素是值类型,例如
-
数组的默认值
- 在数组初始化时,值类型的元素会默认初始化为
0
或默认值。 - 引用类型的元素会被初始化为
null
。
- 在数组初始化时,值类型的元素会默认初始化为
代码示例
数组是引用类型
using System;
class Program
{
static void Main()
{
// 声明一个数组
int[] numbers = { 1, 2, 3, 4, 5 };
// 创建另一个数组变量引用同一数组
int[] anotherNumbers = numbers;
// 修改数组中的值
anotherNumbers[0] = 99;
// 打印结果
Console.WriteLine("Original array: " + string.Join(", ", numbers));
Console.WriteLine("Another array: " + string.Join(", ", anotherNumbers));
}
}
输出:
Original array: 99, 2, 3, 4, 5
Another array: 99, 2, 3, 4, 5
说明:
- 修改
anotherNumbers
时,numbers
也发生了改变,因为它们都指向同一块堆内存。
数组的元素是值类型
using System;
class Program
{
static void Main()
{
int[] numbers = new int[3];
Console.WriteLine("默认值: " + string.Join(", ", numbers));
}
}
输出:
默认值: 0, 0, 0
说明:
- 数组初始化时,值类型的元素被初始化为其默认值(
0
)。
数组的元素是引用类型
using System;
class Program
{
static void Main()
{
string[] strings = new string[3];
Console.WriteLine("默认值: " + string.Join(", ", strings ?? Array.Empty<string>()));
// 修改元素值
strings[0] = "Hello";
strings[1] = "World";
Console.WriteLine("修改后的值: " + string.Join(", ", strings));
}
}
输出:
默认值: , ,
修改后的值: Hello, World,
说明:
- 初始化时,引用类型的元素被设置为
null
。 - 修改时,数组存储的是字符串对象的引用。
总结
-
数组是引用类型
- 数组变量存储的是引用,而不是数组元素本身。
-
内存分配
- 数组对象存储在托管堆中。
- 值类型的元素存储在连续内存中,引用类型的元素存储其引用地址。
-
特性
- 多个变量可以引用同一个数组,修改一个会影响另一个。
- 数组元素的类型(值类型或引用类型)决定了存储方式,但数组始终是引用类型。