Yawen
Yawen

Reputation: 13

C# - Duplicates in List of string Lists instead of proper values

Im reading from xml file using foreach (as in below) and writing found info into a List, which then is later added to a list of lists. My problem is that the moment foreach loop is trying to add another element to my lists of lists it somehow erases the content of previous elements of the list and instead adds x of the same. E.g. first loop is ok, on the second loop it erases the first element and adds 2 of the same, on the 3rd loop it adds 3 same lists etc. It might be a simple problem but i really cannot think of a solution to at the moment.

Code:

static List<List<string>> AddPapers(XmlNodeList nodelist)
    {
        var papers = new List<List<string>>();
        var paper = new List<string>();

        foreach (XmlNode node in nodelist)
        {
            paper.Clear();
            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                    paper.Add(node.ChildNodes[i].InnerText);
            }
            papers.Add(paper);
        }
        return papers;
    }

More info: This is sort of a simplified version without all the fancy stuff id do with the xml but nevertheless, the problem is the same. The paper list is good everytime i check so the problem should be with adding to papers. I honestly have no idea why or even how can it erase the contents of papers and add same values on its own.

Upvotes: 1

Views: 78

Answers (2)

Jawad
Jawad

Reputation: 11364

The issue is with reference. You need to initialize 'paper' instead of clearing it.

Inside you first foreach loop, change

paper.Clear()

With

paper = new List<string>();

When you clear the object, you are keeping the reference to empty object for every index of papers

Upvotes: 1

Rufus L
Rufus L

Reputation: 37020

The problem is that you're only calling paper.Clear, which clears the list that you just added, but then you re-populate it with new items and add it again.

Instead, you should create a new instance of the list on each iteration, so you're not always modifying the same list over and over again (remember a List<T> is a reference type, so you're only adding a reference to the list).

For example:

static List<List<string>> AddPapers(XmlNodeList nodelist)
{
    var papers = new List<List<string>>();        

    foreach (XmlNode node in nodelist)
    {
        // Create a new list on each iteration
        var paper = new List<string>();

        for (int i = 0; i < node.ChildNodes.Count; i++)
        {
            paper.Add(node.ChildNodes[i].InnerText);
        }

        papers.Add(paper);
    }

    return papers;
}

Also, using System.Linq extention methods, your code can be reduced to:

static List<List<string>> GetChildrenInnerTexts(XmlNodeList nodes)
{
    return nodes.Cast<XmlNode>()
        .Select(node => node.ChildNodes.Cast<XmlNode>()
            .Select(child => child.InnerText)
            .ToList())
        .ToList();
}

Upvotes: 3

Related Questions