Почему я не могу повторно инициализировать массив в функции?
В 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;
}
}