[英]Contains() returns false even though it should return true
I am currently trying to check if some list of mine contains an object. 我目前正在尝试检查我的某些列表是否包含一个对象。 The list is a list of of an object which is made up of a struct which contain 2 fields.
该列表是一个对象的列表,该对象由包含2个字段的结构组成。
I am trying to run this small code: 我正在尝试运行这个小代码:
if(m_EatingMoves.Contains(i_Move))
{
....
}
But the expression will return false even though I can surely see on debug that the Move i want is inside the *m_EatingMove* list, I thought that the problem might be that I don't have an override for Equals in my struct so I found an implementation here on StackOverFlow, but the expression still returns false. 但是即使我在调试中可以肯定地看到想要的Move都位于* m_EatingMove *列表中时,该表达式仍会返回false,我认为问题可能是我的结构中没有Equals的替代项,所以我发现StackOverFlow上的实现,但表达式仍然返回false。 Any Idea besides implementing my own Contains() ?
除了实现我自己的Contains()之外的任何想法?
This is the struct: 这是结构:
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;
}
}
Now I have another object which is made up of the above struct: 现在我有另一个由上面的结构组成的对象:
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..)
Finally we have the list which is initialized by the constructor 最后,我们有了由构造函数初始化的列表
private List<Move> m_EatingMoves
You have to provide an override for GetHashCode()
as well as Equals()
. 您必须为
GetHashCode()
以及Equals()
提供覆盖。 Either that, or implement IEquatable<T>
. 要么是,要么实现
IEquatable<T>
。
The Contains
method is a Linq extension, which uses the default equality comparer. Contains
方法是Linq扩展,它使用默认的相等比较器。 From the docs : 来自文档 :
The Default property checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation.
Default属性检查类型T是否实现System.IEquatable接口,如果是,则返回使用该实现的EqualityComparer。 Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
否则,它返回一个EqualityComparer,它使用由T提供的Object.Equals和Object.GetHashCode的覆盖。
You also need to override the GetHashCode
method so that two cells that are equal return the same hash code. 您还需要覆盖
GetHashCode
方法,以便两个相等的单元格返回相同的哈希码。 A pattern often used is to xor the hash codes of items being compared, eg: 经常使用的一种模式是对要比较的项目的哈希码进行异或运算,例如:
public struct Cell
{
[...]
public override int GetHashCode()
{
return Row.GetHashCode() ^ Col.GetHashCode();
}
}
Without overriding this method, data structures may not correctly compare for equality, causing the behavior you observed. 如果不重写此方法,数据结构可能无法正确比较相等性,从而导致您观察到的行为。 The MSDN GetHashCode has additional documentation on how this method is used within the framework.
MSDN GetHashCode有关于如何在框架中使用此方法的其他文档。
I would recommend instead of comparing objects/structs (kinda hardly predictable task with potential multiple side effects) to add sort of unique id to your objects using simple type (eg string) and to use Contains()
based on that id. 我建议您不要比较对象/结构(带有潜在多种副作用的难以预测的任务),使用简单类型(例如字符串)为您的对象添加某种唯一ID,并基于该ID使用
Contains()
。 Moreover, struct
is a value type, thus may causing some problem with boxing/unboxing (might be a case). 此外,
struct
是一种值类型,因此可能会导致装箱/拆箱的一些问题(可能是这种情况)。 Regards, AB 问候,AB
Generally, the the List<T>.Contains
is the generic method comparing elements using the EqualityComparer<T>
. 通常,
List<T>.Contains
是使用EqualityComparer<T>
比较元素的通用方法。 In your case, it calls the Object.Equals
, you could overwrite Object.Equals
. 在你的情况下,它调用
Object.Equals
,你可以覆盖Object.Equals
。
You could refer to MSDN List(T).Contains Method 您可以参考MSDN List(T)。包含方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.