2013-05-08 139 views
2

我目前正在尝试检查我的某个列表是否包含对象。 该列表是由包含2个字段的结构组成的对象的列表。Contains()返回false,即使它应该返回true

我试图运行这个小代码:

if(m_EatingMoves.Contains(i_Move)) 
{ 
    .... 
} 

但表达式将返回false即使我可以肯定看到调试,我想上移是* m_EatingMove *名单内,我认为这个问题可能是因为我的结构中没有对Equals的重写,所以我在StackOverFlow中发现了一个实现,但表达式仍然返回false。除了实现我自己的Contains()之外的任何想法?

这是结构:

public struct Cell 
    { 
     public int Row; 
     public int Col; 

     public Cell(int i_Row, int i_Col) 
     { 
      this.Row = i_Row; 
      this.Col = i_Col; 
     } 

     public override bool Equals(object obj) 
     { 
      if (!(obj is Cell)) 
       return false; 

      Cell cell = (Cell)obj; 
      return cell.Col == Col && cell.Row == Row; 
     } 
    } 

现在我有由上述结构的另一个目的:

public class Move 
    { 
     private Board.Cell m_Source; 
     private Board.Cell m_Destination; 

     public Move(Board.Cell i_Source, Board.Cell i_Destination) 
     { 
      m_Source = i_Source; 
      m_Destination = i_Destination; 
     } 
....(Properties, etc..) 

最后,我们具有通过构造函数中初始化列表

private List<Move> m_EatingMoves 
+2

你还实现了'Equals'为'Move'? – 2013-05-08 01:09:46

+0

你的结构是可变的,[通常是不可取](http://stackoverflow.com/questions/441309/why-are-mutable-structs-vil)。 – Blorgbeard 2013-05-08 01:13:22

+0

@EvanTrimboli,现在你提到它了,我实现了Equal而不是Equals for move,但是我应该在签名中使用覆盖词吗? – Steinfeld 2013-05-08 01:13:50

回答

3

提供的Object.Equals和Object.GetHashCode的覆盖还需要重写GetHashCode方法的EqualityComparer使两个单元是相等的回报相同的哈希码。经常使用的一个模式是异或被比较的项目的散列码,例如:

public struct Cell 
{ 
    [...] 
    public override int GetHashCode() 
    { 
     return Row.GetHashCode()^Col.GetHashCode(); 
    } 
} 

没有重写此方法,数据结构可能无法正确地比较平等,使您观察到的行为。 MSDN GetHashCode有关于如何在框架内使用此方法的其他文档。

3

你必须提供替代GetHashCode()以及Equals()。要么,要么执行IEquatable<T>

Contains方法是一个Linq扩展,它使用默认的相等比较器。从docs

默认属性检查类型T是否实现System.IEquatable接口和,如果是,将返回使用该实现的EqualityComparer。否则,它返回使用由T.

+0

'List '类的一个实际成员名为'Contains',这意味着不应该考虑LINQ版本。 – 2013-05-08 01:19:40

1

我建议不要使用简单类型(例如字符串)将对象/结构(可能难以预测的任务与潜在的多重副作用)添加到对象的唯一ID,并使用基于该ID的Contains()。而且,struct是一个值类型,因此可能会导致一些Boxing/unboxing问题(可能是一种情况)。问候,AB

0

通常,List<T>.Contains是比较使用EqualityComparer<T>的元素的通用方法。在你的情况下,它调用Object.Equals,你可以覆盖Object.Equals

你可以参考MSDN List(T).Contains Method

相关问题