2016-08-30 2 views
-2

В 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 изменить, так как он передан как ссылка на функцию?

+1

'A' является ссылочным объектом. Но вы передаете этот ссылочный объект по значению. @JonSkeet имеет [хорошую статью] (http://jonskeet.uk/csharp/parameters.html) на этом – Jonesopolis

+1

'int []' является ссылочным типом, но 'A' не передается по ссылке. Это два разных термина, которые смешивают многие люди. Термин «ссылочный тип» относится к типам. Термин «pass-by-reference» относится к переменным. Вы можете передать 'A' по ссылке, изменив метод на:' FillArray (ref int [] A) '. –

+0

Хорошее время, чтобы начать читать некоторые документы C# ..... – Eser

ответ

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; 
    } 
} 
1

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

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

2

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

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

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

Смежные вопросы