collections.Contains(T)方法

我使用的是
System.Collections.Generic
,它包含我写的类的实例。 我已经读过,集合
.Contains
方法使用
object.Equals()
,或者来自
IEquatable
接口的
Equals()
方法的实现。 我已经覆盖了对象方法,以及从界面实现。但是,
Queue.Contains(instance)
总是返回false。我究竟做错了什么? 例如...
class Foo : IEquatable<Foo>
{
    ...
    int fooField1;
    ...

    public override bool Equals(object obj)
    {
         Foo other = obj as Foo;
         bool isEqual = false;

         if (other.fooField1 == this.fooField1)
         { 
             isEqual = true;
         }

         return isEqual;         
    }

    public bool Equals(Foo other)
    {
         bool isEqual = false;

         if (other.fooField1 == this.fooField1)
         { 
             isEqual = true;
         }

         return isEqual;         
    }

}
...

void SomeFunction()
{
    Queue<Foo> Q = new Queue<Foo>();
    Foo fooInstance1 = new Foo();
    Foo fooInstance2 = new Foo();

    fooInstance1.fooField1 = 5;
    fooInstance2.fooField1 = 5;

    Q.Enqueue(fooInstanec1);
    if(Q.Contains(fooInstance2) == false)
    {
         Q.Enqueue(fooInstance2);
    }
}
fooInstance2始终添加到队列中。实际上,当我在调试器上运行它时,永远不会达到Equals的实现。 我究竟做错了什么?     
已邀请:
一旦初始编译错误被整理出来,您的示例代码就会按预期工作。并不是它与提出的问题相关,请阅读重写等于(您还需要覆盖GetHashCode并检查错误情况,如null / type-mismatch)。
class Foo : IEquatable<Foo>
    {
        private int _fooField1;
        public Foo(int value)
        {
            _fooField1 = value;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Foo);
        }

        public bool Equals(Foo other)
        {
            return (other._fooField1 == this._fooField1);
        }
    }



    class Program
    {
        static void SomeFunction()
        {
            var Q = new Queue<Foo>();
            Foo fooInstance1 = new Foo(5);
            Foo fooInstance2 = new Foo(5);

            Q.Enqueue(fooInstance1);
            if (!Q.Contains(fooInstance2))
            {
                Q.Enqueue(fooInstance2);
            }
            else
            {
                Console.Out.WriteLine("Q already contains an equivalent instance ");
            }
        }

        static void Main(string[] args)
        {
            SomeFunction();
        }
    }
    
您需要在类Foo中重写GetHashCode()方法。     
fooInstance1.fooField1 = 5;
fooInstance1.fooField2 = 5;
你在那里更新了
fooInstance1
两次。第二行应该说
fooInstance2.fooField1 = 5;
。 一旦修复,
Q.Contains
按预期返回
True
。 除此之外,您不一定需要实施
IEquatable
。每个对象都有一个可覆盖的
Equals
方法。你可以简单地覆盖它。实现自己的比较方法时要小心。此示例中显示的实现对NullReference异常非常开放。这样的事情会更好:
public override bool Equals(object obj)
{
    if(obj == null)
        return false;

    Foo other = obj as Foo;
    if(other == null)
        return false;

    return fooField1 == other.fooField1;
}
正如其他人所提到的,如果你走这条路并覆盖
Equals
,你也应该覆盖
GetHashCode
。您还应该考虑其他一些事情。有关详细信息,请参阅此MSDN页面。     
为什么在C#中覆盖Equals方法时重写GetHashCode很重要?     

要回复问题请先登录注册