开发者

When I add a new item to a List<List<string>> each item of the parent list get the same values

Apologies if the answer to this is obvious, I'm fairly new to C# and OOP. I've stepped though my code and spent quite some time on Google but I can't find the answer to my question (quite possibly because I am using the wrong search terms!).

I have the following class that creates a static List<List<string>> and has a method to add items to that list:

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

Else where I create a List<string> which I pass into the Record() method to be added to _WordList. The problem is when I add items to WordList it gives every item in that list the same value. e.g.:

1st item added contains "Foo" and "bar"

2nd item added contains "Not","Foo" and "bar"

So instead of a list that looks like:

1: "Foo","bar"
2: "Not","Foo","bar"

I end up with:

1: "Not","Foo","bar"
2: "Not","Foo","bar"

I haven't used a List<string[]> instead of a List<List<string>> because the way I am getting the List<string> to add is by reading a text file line by line with a delimiter saying when I should add the List<string> and clear it so I can start again. Therefore I don't kn开发者_Go百科ow how long an array I need to declare.

Hope this makes some kind of sense! If you need anymore of the code posting to help let me know.

Thanks, in advance.

EDIT

Here is the code for the creation of the List<string> that is passed to the Record() method. I think I see what people are saying about not creating a new instance of the List<string> but I'm not sure how to remedy this in regards to my code. I will have a think about it and post an answer if I come up with one!

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();
    }


Instead of

WordList.Record(WordsToAdd);
WordsToAdd.Clear();
WordsToAdd.Add(line.Replace("$", ""));

do

WordList.Record(WordsToAdd);
WordsToAdd = new List<string>();
WordsToAdd.Add(line.Replace("$", ""));


All that your Record method is doing is adding a reference to the List<string> you've passed to it. You then clear that same list, and start adding different strings to it.

Maybe something like:

public static void Record(IEnumerable<string> Words)
{
    _WordList.Add(Words.ToList());
}

Which will force a copy to occur; also, by accepting IEnumerable<string>, it puts less restrictions on the code that calls it.


Can you post the code that adds the list - I bet you are doing something like

  1. create a list l
  2. add it
  3. modify l
  4. add it

This result in a single object (because you created it only once) with multiple references to it, namely from the first value in _WordList, from the second value in _WordList, from l.

So the right way to do it is:

  1. create list l
  2. add it
  3. create NEW list l
  4. add it

Or in code:

List<string> l = new string[] { "Foo", "bar" }.ToList();
WordList.Record(l);
l = new string[] { "Not", "Foo", "bar" }.ToList();
WordList.Record(l);


You haven't shown how you are adding items to the list. Here's an example which works as expected:

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();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜