在C#中的参数传递中,数组默认是按引用传递的,这意味着我们把一个数组传递到方法后,方法便可以更改这个数组内的任意元素,这在某些时候是非常有用的;
但我们应该考虑别外一种情况:我们传递给方法的是一个临时数组,将会发生什么事情?在方法中这个数组可能被定义为某个很重要的信息,也一个结构或者是一个可序列化的类的属性,这时如果我们不加考虑地把这个临时数组传递到方法内,后果可想而知。
这个,我们应该避免按引用的方式传递数组,但.NET好像并没有设计按值传递的方法传递数组(如果我说错了,请原谅我的无知),一种折衷的方案是使用Array类的Copy方法将数组内的元素拷贝到目标数组。来看一段测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestArrayReference
{
class Program
{
static int[] A;
static int[] B;
static void Main(string[] args)
{
/* 注意请不要拿string数组做测试,
因为string类型本身是不支持内容变动的,
所有对string类型变量(对象)进行的更改都将产生一个新的string类型的临时变量*/
A = new int[] { 1, 2, 3 };
B = new int[] { 0, 0, 0 };
//打印数组
Console.Write("数组A:");
PrintArray(A);
Console.Write("数组B:");
PrintArray(B);
startTest:
Console.Write("测试传址还是传值?(a/b)");
//根据输入,判断将要执行哪个测试
ConsoleKeyInfo cki = Console.ReadKey();
Console.WriteLine();
Console.WriteLine();
switch (cki.Key)
{
case ConsoleKey.A:
Console.WriteLine("开始传址测试");
TestByRef(A);
break;
case ConsoleKey.B:
Console.WriteLine("开始传值测试");
TestByVal(A);
break;
default:
goto startTest;
}
////更新数组A
Console.WriteLine();
Console.Write("更新数组A为:");
for (int i = 0; i < A.Length; i++)
{
A[i] = A[i] + 1;
Console.Write(A[i]);
}
Console.WriteLine();
////打印数组A
Console.WriteLine();
Console.WriteLine("现在两个数组的内容是:");
Console.Write("数组A:");
PrintArray(A);
Console.Write("数组B:");
PrintArray(B);
////程序结束
Console.ReadKey();
}
static void PrintArray(int[] array)
{
foreach (int i in array)
{ Console.Write(" " + i.ToString()); }
Console.WriteLine();
}
static void TestByVal(int[] array)
{
Console.WriteLine("以传值方式,将数组A赋给数组B");
Array.Copy(array, B, array.Length);
}
static void TestByRef(int[] array)
{
Console.WriteLine("以传址方式,将数组A赋给数组B");
B = array;
}
}
}
在这段代码里,执行TestByRef 方法时,将数组B设置成了对数组A的引用,那么在数组A变动后,数组B中的元素自然也会跟着变动,因为它已经是对数组A的引用,说白了它们两个是内存中的同一块区域。

而在执行TestByVal()方法时,只是将数组A的值拷贝到了数组B,数组A与数组B仍保持对原有内存地址的引用,彼此自身的改变也就不会影响到对方。

浙公网安备 33010602011771号