При добавлении нового элемента в список> каждый элемент родительского списка получает одинаковые значения
Если ответ на этот вопрос очевиден, я довольно новичок в C# и OOP. Я прошел через свой код и провел довольно много времени в Google, но я не могу найти ответ на свой вопрос (вполне возможно, потому что я использую неправильные условия поиска!).
У меня есть следующий класс, который создает статический List<List<string>> и имеет метод для добавления элементов в этот список:
public static class WordList
{
static List<List<string>> _WordList; // Static List instance
static WordList()
{
//
// Allocate the list.
//
_WordList = new List<List<string>>();
}
public static void Record(List<string> Words)
{
//
// Record this value in the list.
//
_WordList.Add(Words);
}
}
Еще где я создаю List<string>, который я передаю в метод Record(), чтобы добавить к _WordList. Проблема в том, когда я добавляю items to WordList он дает каждому элементу в этом списке одинаковое значение. например:
1-й добавленный пункт содержит "Foo " и"bar"
2-й добавленный пункт содержит "не"," Foo "и"bar"
Поэтому вместо списка, который выглядит так:
1: "Foo","bar"
2: "Not","Foo","bar"
Я заканчиваю словами:
1: "Not","Foo","bar"
2: "Not","Foo","bar"
Я не использовал List<string[]> вместо List<List<string>>, потому что способ, которым я получаю List<string>, чтобы добавить, заключается в чтении текстового файла строка за строкой с разделителем, говорящим, когда я должен добавить List<string> и очистить его, чтобы я мог начать снова. Поэтому я не знаю, какой длины массив мне нужно объявить.
Надеюсь, что это имеет какой-то смысл! Если вам понадобится еще один код, чтобы помочь, дайте мне знать.
Заранее благодарю.
EDIT
Вот код для создания List<string>, который передается в метод Record(). Я думаю, что понимаю, что люди говорят о том, чтобы не создавать новый экземпляр List<string>, но я не уверен, как исправить это в отношении моего кода. Я подумаю немного. об этом и напишите ответ, если я его придумаю!
public static void LoadWordList(string path)
{
string line;
List<string> WordsToAdd = new List<string>();
StreamReader file = new System.IO.StreamReader(path);
while ((line = file.ReadLine()) != null)
{
if (line.Substring(0, 1) == "$")
{
WordList.Record(WordsToAdd);
WordsToAdd.Clear();
WordsToAdd.Add(line.Replace("$", ""));
}
else
{
WordsToAdd.Add(line.Replace("_"," "));
}
}
file.Close();
}
4 ответов:
Все, что делает ваш метод
Record, это добавляет ссылку наList<string>, которую вы ему передали. Затем вы очищаете тот же самый список и начинаете добавлять в него различные строки.Может быть, что-то вроде:
public static void Record(IEnumerable<string> Words) { _WordList.Add(Words.ToList()); }, что приведет к возникновению копии; кроме того, принимая
IEnumerable<string>, он накладывает меньше ограничений на вызывающий его код.
Вместо
WordList.Record(WordsToAdd); WordsToAdd.Clear(); WordsToAdd.Add(line.Replace("$", ""));Do
WordList.Record(WordsToAdd); WordsToAdd = new List<string>(); WordsToAdd.Add(line.Replace("$", ""));
Можете ли вы разместить код, который добавляет список-я уверен, что вы делаете что-то вроде
- Создайте список l
- добавьте его
- изменить l
- добавьте его
Это приводит к одному объекту (поскольку вы создали его только один раз) с несколькими ссылками на него, а именно из первого значения в _WordList, из второго значения в _WordList, из l.
Итак, правильный способ сделать это:
- создать список l
- добавьте его
- создать новый список l
- добавьте его
Или в коде:
List<string> l = new string[] { "Foo", "bar" }.ToList(); WordList.Record(l); l = new string[] { "Not", "Foo", "bar" }.ToList(); WordList.Record(l);
Вы не показали, как вы добавляете элементы в список. Вот пример, который работает как ожидалось:
using System; using System.Collections.Generic; using System.Linq; public static class WordList { static List<List<string>> _WordList; // Static List instance static WordList() { _WordList = new List<List<string>>(); } public static void Record(List<string> Words) { _WordList.Add(Words); } public static void Print() { foreach (var item in _WordList) { Console.WriteLine("-----"); Console.WriteLine(string.Join(",", item.ToArray())); } } } class Program { static void Main() { WordList.Record(new[] { "Foo", "bar" }.ToList()); WordList.Record(new[] { "Not", "Foo", "bar" }.ToList()); WordList.Print(); } }
Comments