Не передается ссылка на массив С#
Массив ссылочный тип данных, и если мы присвоим один массив другому, то передастся ссылка. (по идее)
static void Main(string[] args)
{
int[] nums1 = new int[] { 9 ,10,10,15,0,0,0,0};
int[] nums2 = new int[] { 10, 11, 12, 12 };
Merge(nums1,nums2);
foreach (int i in nums1)
{
Console.WriteLine(i);
}
}
static public void Merge(int[] nums1, int[] nums2)
{
int[] newNums = new int[nums1.Length];
...
nums1 = newNums;
}
И после выхода из такого вида метода nums1 не поменялся. Объясните почему массив ведет себя так. И я смотрел по отладчику, что nums1 был равен newNums до выхода из метода. Но после выхода nums1 стал равен первоначальному. Если через чикл присвоить те же значения, или передать через ref,то все будет в порядке.
Ответы (3 шт):
Переменная nums1 является локальной которая хранит ссылку на объект массива в памяти.
Передавая массив nums1 в метод значение переменной копируется, т. е. копируется только то, что хранится в самой переменной, а именно - ссылка, а не сам массив. Изменив скопированную ссылку оригинал не поменяется. Если же вы измените сам массив (а не создадите новый), то изменится как раз таки содержимое оригинального массива.
В C++ аналогичной записью будет:
int fn(int* arr) {arr = new int[] {...};}
arr = new int[] {...};
fn(arr);
Параметр ref в свою очередь передаёт значение по ссылке. Т. к. значение nums1 - ссылка, то с помощью ref передаётся ссылка на ссылку (на адресс в памяти, хранящий список значений).
В C++ аналогичной записью будет:
int fn(int** arr) {*arr = new int[] {...};}
arr = new int[] {...};
fn(&arr);
Или просто
int fn(int*& arr) {arr = new int[] {...};}
arr = new int[] {...};
fn(arr);
P. S.: Вы всё равно создаёте новый массив, так почему бы его не возвращать через return? Это гораздо понятнее и логичнее.
Используйте ключевое слово ref. Вот так будет выглядеть ваш метод в этом случае:
static public void Merge(ref int[] nums1, int[] nums2)
{
int[] newNums = new int[nums1.Length];
...
nums1 = newNums;
}
Либо возвращайте какой-то результат работы вашего метода:
static public int[] Merge(int[] nums1, int[] nums2)
{
int[] newNums = new int[nums1.Length];
...
return newNums;
}
static void Main(string[] args)
{
int[] nums1 = new int[] { 9 ,10,10,15,0,0,0,0};
int[] nums2 = new int[] { 10, 11, 12, 12 };
int[] result = Merge(nums1,nums2);
foreach (int i in result)
{
Console.WriteLine(i);
}
}
Для передачи массива по ссылке используется ключевое слово ref. Попробуй передать массив через него:
static public int[] Merge(ref int[] nums1, int[] nums2)
{
// Пример: создадим новый массив и переназначим переменной nums1
nums1 = new int[nums1.Length];
// Заполняем новый массив какими-либо значениями (например, нулями)
Random rnd = new Random();
for (int i = 0; i < nums1.Length; i++)
{
nums1[i] = rnd.Next(-10, 10);
}
return nums1;
}
static void Main(string[] args)
{
int[] nums1 = new int[] { 9, 10, 10, 15, 0, 0, 0, 0 };
int[] nums2 = new int[] { 10, 11, 12, 12 };
// При вызове метода добавляем ключевое слово "ref"
int[] result = Merge(ref nums1, nums2);
// Теперь массив nums1 переназначен внутри метода и это изменение видно здесь:
foreach (int i in result)
{
Console.WriteLine(i);
}
}