Contains()返回false,即使它应该返回true
本文关键字:返回 true false Contains | 更新日期: 2023-09-27 18:12:48
我目前正在检查我的一些列表是否包含一个对象。列表是一个对象的列表,该对象由包含两个字段的结构体组成。
我正在尝试运行这个小代码:
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
您还需要重写GetHashCode
方法,以便两个相等的单元格返回相同的哈希码。一种常用的模式是比较项目的哈希码,例如:
public struct Cell
{
[...]
public override int GetHashCode()
{
return Row.GetHashCode() ^ Col.GetHashCode();
}
}
如果不重写此方法,数据结构可能无法正确比较相等性,从而导致您所观察到的行为。MSDN GetHashCode有关于如何在框架内使用此方法的附加文档。
您必须为GetHashCode()
和Equals()
提供覆盖。要么这样,要么实现IEquatable<T>
。
Contains
方法是Linq的扩展,它使用默认的相等比较器。来自文档:
Default属性检查类型T是否实现了System。接口,如果是,则返回使用该实现的EqualityComparer。否则,它返回一个使用Object的重写的EqualityComparer。等号和对象。
提供的GetHashCode
我建议不要比较对象/结构(有点难以预测的任务,有潜在的多重副作用),而是使用简单类型(例如字符串)为对象添加某种唯一id,并基于该id使用Contains()
。此外,struct
是一个值类型,因此可能会导致装箱/拆箱的一些问题(可能是一种情况)。问候,AB
一般来说,List<T>.Contains
是使用EqualityComparer<T>
比较元素的泛型方法。在您的例子中,它调用Object.Equals
,您可以覆盖Object.Equals
。
您可以参考MSDN列表(T)。包含方法