C# 中的数组是引用类型
在 C# 中,无论数组存储的是值类型(如 int、double)还是引用类型(如 string、object),数组本身总是 引用类型。
这意味着:
- 数组在内存中分为两部分:引用存储在栈中,实际数据存储在堆中。
- 当数组作为参数传递给方法时,传递的是对数组的引用,因此方法内对数组内容的修改会影响原数组。
示例:数组作为引用类型
方法中修改数组元素
using System;
class Program
{
static void ModifyArray(int[] arr)
{
// 修改数组的第一个元素
arr[0] = 100;
}
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine("Before modification: " + numbers[0]); // 输出 1
ModifyArray(numbers);
Console.WriteLine("After modification: " + numbers[0]); // 输出 100
}
}
说明:
- 数组 numbers 作为参数传递给 ModifyArray 方法。
- 方法中通过引用修改了数组的内容。
- 修改影响到了原数组,因为传递的是对数组的引用。
如何在方法中防止数组被修改?
如果希望数组在方法中不被修改,可以使用 readonly 修饰符 或在调用时传递 数组的副本。
使用readonly修饰符
static void DisplayArray(in int[] arr)
{
// arr 是只读的,无法修改其内容
// arr[0] = 100; // 编译错误
foreach (var item in arr)
{
Console.WriteLine(item);
}
}
传递数组副本
static void ModifyArrayCopy(int[] arr)
{
arr[0] = 100; // 修改副本,不影响原数组
}
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
int[] numbersCopy = (int[])numbers.Clone(); // 创建数组副本
ModifyArrayCopy(numbersCopy);
Console.WriteLine("Original array: " + numbers[0]); // 输出 1
}
如何完全更改数组的引用?
在方法中,如果试图更改数组引用(指向一个新数组),这种修改不会影响到调用方的数组。
示例:更改引用
static void ChangeArrayReference(int[] arr)
{
arr = new int[] { 100, 200, 300 }; // 更改数组的引用
}
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
ChangeArrayReference(numbers);
Console.WriteLine(numbers[0]); // 输出 1,引用未改变
}
总结
特性 | 说明 |
数组类型 | 数组是引用类型,无论存储的元素是值类型还是引用类型。 |
传递方式 | 数组作为参数传递时,传递的是对数组的引用,因此方法中可以修改数组内容。 |
防止修改方法 | 使用 readonly 修饰符或传递数组副本以保护原数组。 |
更改数组引用 | 方法中直接更改数组的引用不会影响调用方的数组,除非使用 ref 或 out 关键字。 |
额外:使用ref或out更改数组的引用
如果需要让方法修改数组的引用,必须使用 ref 或 out 关键字。
static void ReplaceArray(ref int[] arr)
{
arr = new int[] { 100, 200, 300 }; // 修改数组引用
}
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
ReplaceArray(ref numbers);
Console.WriteLine(numbers[0]); // 输出 100,引用已更改
}