Почему я не могу повторно инициализировать массив в функции?

В 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 ответа

Когда FillArray начинает работать, у него есть переменная с именем A, которая указывает на массив, который вы настроили в main (по совпадению называемый A)

Во втором случае вы меняете локальную точку A так, чтобы она указывала на другой массив. Поэтому любые изменения, которые вы делаете, не видны вызывающим кодом - нет никакой связи между переменными 2 A

На самом деле это не передача параметра "по ссылке", поскольку изменение переданного значения (A) не отражается в пространстве вызывающих. Вы получаете "указатель" по значению (в кавычках, поскольку C# будет утверждать, что это не указатель, поскольку в управляемом коде нет указателей)

Внутренне адрес массива - это то, что передается. Изменяя элементы в этом массиве, вызывающая сторона увидит эти изменения. Но если вы назначите массив новому массиву, он больше не будет указывать на массив вызывающего. И вызывающая сторона не увидит никаких изменений в этом массиве.

Таким образом, хотя массив передается по ссылке, сама ссылка передается по значению, если вы не используете ref ключевое слово.

Вы можете изменить значения, содержащиеся в массиве, 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;
    }
}
Другие вопросы по тегам