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



Если ответ на этот вопрос очевиден, я довольно новичок в 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();
}
490   4  

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("$", ""));

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

  1. Создайте список l
  2. добавьте его
  3. изменить l
  4. добавьте его

Это приводит к одному объекту (поскольку вы создали его только один раз) с несколькими ссылками на него, а именно из первого значения в _WordList, из второго значения в _WordList, из l.

Итак, правильный способ сделать это:

  1. создать список l
  2. добавьте его
  3. создать новый список l
  4. добавьте его

Или в коде:

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

    Ничего не найдено.