【问题标题】:List<T> clearing in a For Loop unexpectedlyList<T> 在 For 循环中意外清除
【发布时间】:2015-03-13 09:03:01
【问题描述】:

这个错误把我难住了!本质上,代码接收一个名为“停车”的对象列表。我想将Parking 对象与类似的Title 分组。为此,我考虑在列表中创建一个列表 - TerminalCollectionParking 对象的列表和一个供参考的名称。

为了帮助我解决这个问题,我创建了一个新的 - 临时 - terminal 对象,它是 Parking 对象的列表。每当我在同一类别中找到 Parking 对象时,我会将其添加到临时 terminal 中,直到找到不适合的对象。发生这种情况时,我将terminal 列表与名称结合起来创建TerminalCollection 对象。然后我通过将下一批类似的Parking 对象添加到终端来重新开始这个过程。

我发现的问题是,当我想在创建包含此列表副本的TerminalCollection 对象后清除terminal 列表时,该列表也会从TerminalCollection 对象中清除!!我不知道为什么,因为我认为我正在创建一个新列表并将terminal 的副本分配给它?为什么新列表会与原始terminal 共享相同的内存?有没有我误解的基本概念?非常感谢您提供解决此问题的任何帮助和建议! :)

private static List<TerminalCollection> Terminals(List<Parking> input)
    {
        List<TerminalCollection> Terminals = new List<TerminalCollection>();
        List<Parking> terminal = new List<Parking>();
        int current = 0;
        int currentpos = 0;
        string currentname = "";
        bool clearbuffer = false;
        foreach (Parking attempt in input)
        {
            if (clearbuffer)
            {
                terminal.Clear();
                clearbuffer = false;
            }
            if (current != 0)
            {
                int checknew = int.Parse(Regex.Match(attempt.Title, @"\d+").Value);
                if (checknew - current == 0 && Regex.Match(attempt.Title, @"\d+").Index == currentpos)
                {
                    //Matches same terminal, so slot added in temporary terminal list  
                    terminal.Add(attempt);
                    currentname = Regex.Match(attempt.Title, @"^.*?\d+").Value;
                } 
                else
                {
                    //Clears and starts again (resets current and currentpos)
                    current = checknew;
                    currentpos = Regex.Match(attempt.Title, @"\d+").Index;
                    TerminalCollection final = new TerminalCollection();
                    final.Slots = terminal;
                    final.Name = currentname;
                    //One terminal added to global collection of terminals
                    Terminals.Add(final);
                    //Temporary terminal list cleared
                    clearbuffer = true;
                }
            }
            else { 
            //Gets first integer  
            current = int.Parse(Regex.Match(attempt.Title, @"\d+").Value);
            currentpos = Regex.Match(attempt.Title, @"\d+").Index;
            terminal.Clear();
            //Adds first element to start a new terminal
            terminal.Add(attempt);
            }
        }
        return null;
    }

【问题讨论】:

  • "一个包含此列表副本的 TerminalCollection 对象"...它不包含该列表的副本。它包含对列表的引用的副本。

标签: c# list class foreach


【解决方案1】:

Clear不会创建新列表,分配也不会。您只需在循环之前创建一次列表,因此 每个 对象都会指向它。

您将此清单视为清除“其他”列表(实际上它们都是相同的列表)。

你需要改成这样:

if (clearbuffer)
{
   terminal = new List<Parking>();
   clearbuffer = false;
}

现在每个迭代都有其自己的列表对象,您不会看到对它的更改会影响其他实例。

总的来说,考虑重新设计那个循环,它真的令人困惑。

【讨论】:

  • 击败我@BradleyDotNET - 忽略我对 empty() 的评论。 :)
  • 对于某人来说似乎是另一个重新了解引用类型的机会。 :)
  • 非常感谢@BradleyDotNET,我想这确实是基本理解的失败! :) 我会看看 MSDN 上的引用类型。我是通过尝试来完成这一切的,所以我一定会看看我是否可以改进我的循环!谢谢! :)
猜你喜欢
  • 1970-01-01
  • 2017-07-14
  • 2020-06-06
  • 2012-07-14
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
相关资源
最近更新 更多