С# "смешные" проблемы со списком <String []>

У меня есть некоторые странные проблемы со списком в моем приложении С#. Это должна быть ошибка распределения или что я делаю что-то неправильно (я средний разработчик С#). Позвольте мне привести пример, близкий к моим строкам:

List<String[]> MyPrimaryList = new List<String[]>();
List<String[]> MySecondaryList = new List<String[]>();
String[] array;

String arrayList = "one,two,three,four,five";
array = arrayList.Split(',');

MyPrimaryList.Add(array);
MySecondaryList.Add(array);

MyPrimaryList[0][0] += "half";

Итак, теперь я ожидаю, что первое значение в первом массиве в MyPrimaryList будет "onehalf" и "one" в MySecondaryList. Но проблема/проблема в том, что оба списка обновляются с "onehalf" как первое значение в первом массиве в обоих списках.

Есть ли у вас хорошее объяснение?:)

СПАСИБО!!

Ответ 1

String[] array; является ссылочным типом. Вы добавили ссылку на местоположение в памяти этого объекта для обоих списков, поэтому они оба сохраняют одни и те же данные.

Если вам нужен второй список, чтобы иметь копию array, вы можете использовать Array.Copy:

List<String[]> MyPrimaryList = new List<String[]>();
List<String[]> MySecondaryList = new List<String[]>();

String arrayList = "one,two,three,four,five";
String[] array = arrayList.Split(',');
String[] array2 = new string[5];

Array.Copy(array, array2, 5);

MyPrimaryList.Add(array);
MySecondaryList.Add(array2);

MyPrimaryList[0][0] += "half";

Console.WriteLine(MyPrimaryList[0][0]);
Console.WriteLine(MySecondaryList[0][0]);

Это берет исходный массив, массив назначения и длину - будьте осторожны, чтобы проверить границы массива.

Выводится:

onehalf
one

Поскольку каждый список теперь содержит ссылку на другой массив, вы можете самостоятельно управлять элементами массива.

Ответ 2

Вы добавляете один и тот же экземпляр массива в оба списка, поэтому они указывают на одну и ту же структуру памяти.

Если вы хотите, чтобы они были независимыми, вам нужно клонировать их; Быстрый способ от вершины моей головы будет использовать linq list.Add(array.ToArray()) в одном из списков

Ответ 3

Массивы являются ссылочными объектами, поэтому вы изменяете одну и ту же коллекцию в памяти. Все, что вы делаете, по существу добавляет указатели к одной и той же структуре,

Взгляните на эту документацию

Передача массивов в качестве аргументов (Руководство по программированию на С#)

Вам понадобится сделать глубокую копию массива, чтобы получить нужную вам автономию.

Вы можете сделать это с помощью Array.Copy

Ответ 4

Вам нужно создать массив для каждого списка, с которым вы работаете, потому что прямо сейчас вы указываете на ту же структуру памяти

правильный код должен быть:

List<String[]> MyPrimaryList = new List<String[]>();
List<String[]> MySecondaryList = new List<String[]>();
String[] array;
String[] secondaryArray;

String arrayList = "one,two,three,four,five";
array = arrayList.Split(',');
secondaryArray = arrayList.Split(',');

MyPrimaryList.Add(array);
MySecondaryList.Add(secondaryArray);

MyPrimaryList[0][0] += "half";

теперь ваш второй список будет иметь "один", а не "onehalf", как первый элемент

Ответ 5

Как упоминалось, массив является ссылочным типом, и поэтому оба списка указывают на один и тот же массив


Чтобы решить вашу проблему, используйте метод Clone.

MyPrimaryList.Add((String[])array.Clone());
MySecondaryList.Add((String[])array.Clone());

Хотя он сделал бы мелкую копию этого массива, но он был бы подходящим в вашем случае