C#List.Remove(item)故障?

时间:2014-03-21 19:55:10

标签: c#

今天,我在C#列表中遇到了一个小故障,或者至少看起来像是我的一个,所以我想我会问。这是代码:

// in main
List<Move> LM = new List<Move>();
LM.Add(new Move(4, 7));

// in Move
public Move(int ccc, int rrr)
{
  col = ccc;
  row = rrr;

  scr_check_duplicates();
}

public void scr_check_duplicates()
{
  foreach (Move M in Main.LM)
  {
    if (M.col == col && M.row == row)
      Main.LM.Remove(this);
  }
}

猜猜是什么?删除()没有做任何事情!如果你想自己搞清楚,请继续。否则,原因如下:

在追踪它一段时间后,我相信它是因为在新的Move()构造函数的中间,该对象实际上还没有被添加到列表中,因为它&#39;还在初始化。

问题是,这是故障还是C#故意这样做?在我看来,如果它只是继续添加一个新的Move,然后调用构造函数,它将工作正常,而不会破坏任何可想到的代码。有没有更好的方法来做我想要的?理想情况下,我希望能够立即删除构造函数或其调用的任何函数。

3 个答案:

答案 0 :(得分:5)

没有任何故障。想想先执行什么。你的代码与此相同......

// in main
List<Move> LM = new List<Move>();
Move move=new Move(4, 7);
LM.Add(move);

因此构造函数在项目添加到列表之前完全运行。因此,在您致电Main.LM.Remove(this);时,该项目尚未在LM中,因此无需删除。

此外,当您在一个遍历该集合的foreach块内时,您无法在集合上调用Remove。

答案 1 :(得分:1)

  

在我看来,如果它只是继续添加一个新的Move,然后调用构造函数

这不是它的工作原理。为了将对象传递给Add,它必须具有实例。这是您在致电new Move(...)时创建的内容。所以在这个结构中,c'tor必须先运行,然后添加。

答案 2 :(得分:0)

上面的答案阐明了为什么你会得到你的行为。

为了正确处理,我建议使用HashSet。它会阻止您添加重复值。您需要覆盖对象上的.Equals和.GetHashCode方法,以告诉对象是否相等。但是,这会使您的集合不会包含重复值。