今天,我在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,然后调用构造函数,它将工作正常,而不会破坏任何可想到的代码。有没有更好的方法来做我想要的?理想情况下,我希望能够立即删除构造函数或其调用的任何函数。
答案 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方法,以告诉对象是否相等。但是,这会使您的集合不会包含重复值。