为什么我不能在函数中重新初始化数组?

时间:2016-08-30 19:04:31

标签: c# arrays pass-by-reference pass-by-value

在C#中,数组通过引用传递给函数,这意味着这段代码:

static void FillArray(int[] A) {
     for (int i = 0; i < A.Length; i++) {
          A[i] = -1;
     }
}

static void Main(string[] args) {
    int[] A = new int[10];

    FillArray(A);

    Console.WriteLine(string.Join(" ", A));
}

将生成-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 这是预期的答案。但是如果我像这样重新初始化数组:

static void FillArray(int[] A) {
    A = new int[2*A.Length];
    for (int i = 0; i < A.Length; i++) {
        A[i] = -1;
    }
}

输出为0 0 0 0 0 0 0 0 0 0 !!

不应该A更改,因为它是作为对函数的引用传递的吗?

3 个答案:

答案 0 :(得分:2)

当FillArray开始运行时,它有一个名为A的变量,它指向你在main中设置的数组(巧合地称为A)

在第二种情况下,您将本地A更改为指向其他阵列。因此,调用代码看不到您所做的任何更改 - 2个A变量之间没有任何关系

实际上这不是'通过引用'参数传递,因为更改传递的值(A)不会反映在调用者空间中。你是按值得到一个'指针'(在引号中,因为c#会认为它不是指针,因为托管代码没有指针)

答案 1 :(得分:1)

您可以更改数组A中包含的值,但不能更改A。调用方法时,实际传递参数值的副本(默认情况下)。如果您想要更改A,则必须使用ref关键字通过引用传递它:

static void FillArray(ref int[] A) {
    A = new int[2*A.Length];
    for (int i = 0; i < A.Length; i++) {
        A[i] = -1;
    }
}

答案 2 :(得分:1)

在内部,数组的地址是传递的内容。通过修改该数组中的项目,调用者将看到这些更改。但是,如果将数组分配给新数组,则它不再指向调用者的数组。并且调用者不会看到该数组的任何更改。

因此,当数组通过引用传递时,除非使用ref关键字,否则引用本身将按值传递。