简体   繁体   English

Contains()返回false,即使它应该返回true

[英]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.

相关问题 为什么typeof(T).IsEnum返回true,即使文档说它应该总是返回false? - Why does typeof(T).IsEnum return true, even though the documentation says it should always return false? IsAssignableFrom() 在应该返回 true 时返回 false - IsAssignableFrom() returns false when it should return true 异步函数返回false,但应返回true - Async function returns false but should return true 布尔 OR 语句返回 FALSE,即使其中一侧为 TRUE - Boolean OR statement returns FALSE even though one of the sides is TRUE 为什么Contains()返回false但是在列表中包装并且Intersect()返回true? - Why does Contains() return false but wrapping in a list and Intersect() returns true? if/else 语句返回假,即使条件应该为真。 (C#) - If/else statement is returning false, even though the condition should be true. (C#) 为什么C#是关键字,对于double返回true,但是对于float而言为false,即使转换为float也有效? - Why does C# is keyword return true for double, but false for float even though casting to float works? Queue.Contains 返回 false 而不是 true - Queue.Contains returns false instead of true OnClientClick回发,即使在7上返回false - OnClientClick postback even though return false on ie 7 即使if语句为true,函数也会返回false - Functions returns false even when the if statement is true
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM