【问题标题】:C# - Duplicates in List of string Lists instead of proper valuesC# - 在字符串列表列表中重复而不是正确的值
【发布时间】:2019-12-12 21:59:33
【问题描述】:

我正在使用 foreach(如下所示)从 xml 文件中读取并将找到的信息写入列表,然后将其添加到列表列表中。我的问题是,当 foreach 循环试图将另一个元素添加到我的列表中时,它会以某种方式删除列表中先前元素的内容,而是添加相同的 x。例如。第一个循环没问题,在第二个循环它删除第一个元素并添加 2 个相同的元素,在第三个循环它添加 3 个相同的列表等。 这可能是一个简单的问题,但我现在真的想不出解决方案。

代码:

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

更多信息:这是一个简化版本,没有 id 对 xml 所做的所有花哨的东西,但问题是一样的。 paper 列表在我每次检查时都很好,所以问题应该是添加到 papers。老实说,我不知道为什么或什至如何删除论文的内容并自行添加相同的值。

【问题讨论】:

  • 这不是答案,但ListRemove 方法。你看见了吗?也许你会在这种情况下使用它。
  • 也许尝试通过将纸张转换为带有paper.ToArray() 的数组并添加一个范围来将纸张添加到纸张。我认为问题在于您通过引用添加到论文中,然后清除列表,尽管我不是 100% 确定这一点。
  • 你不是必须使用 list.AddRange(listToAdd) 到初始列表吗?
  • 如果您可以更改为IEnumerable&lt;XElement&gt; nodelist,那么您可以这样做:return nodelist.Select(n =&gt; n.Elements().Select(x =&gt; x.Value).ToList()).ToList();

标签: c# .net xml


【解决方案1】:

问题在于您只调用了paper.Clear,这会清除您刚刚添加的列表,但随后您会用新项目重新填充它并再次添加。

相反,您应该在每次迭代时创建列表的 新实例,这样您就不必一遍又一遍地修改同一个列表(请记住 List&lt;T&gt; 是引用类型,所以你只是向list添加一个引用

例如:

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

此外,使用System.Linq 扩展方法,您的代码可以简化为:

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

【讨论】:

  • 很高兴看到我几乎是正确的。 C# 对引用类型的不明确性有时会令人愤怒。
  • 现在可以使用了,谢谢。我怀疑我错过了一些简单的事情。
【解决方案2】:

问题与参考有关。您需要初始化 'paper' 而不是清除它。

在你的第一个foreach循环中,改变

paper.Clear()

paper = new List&lt;string&gt;();

当您清除对象时,您会为每个论文索引保留对空对象的引用

【讨论】:

    猜你喜欢
    • 2013-01-15
    • 2021-10-18
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多