collections.Contains(T) 方法
我正在使用 System.Collections.Generic,其中包含我编写的类的实例。
我读到集合 .Contains
方法使用 object.Equals()
,或者 Equals()
方法的实现>IEquatable 接口。
我已经重写了对象方法,并从接口实现。但是,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 的实现。
我做错了什么?
I am using a System.Collections.Generic
, which contains instances of a class I wrote.
I have read that the collections .Contains
method uses object.Equals()
, or an implementation of the Equals()
method from the IEquatable
interface.
I have overridden the object method, as well as implemented from the interface. However, Queue.Contains(instance)
is always returning false. What am I doing wrong?
For instance...
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 is always added to the queue. In fact, when I run this on the debugger, the implementations of Equals are never reached.
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您还需要在 Foo 类中重写 GetHashCode() 方法。
You need GetHashCode() method overridden as well in your class Foo.
您在那里更新了两次
fooInstance1
。第二行应该是fooInstance2.fooField1 = 5;
。修复此问题后,
Q.Contains
将按预期返回True
。Other than that, you don't necessarily need to implement
IEquatable
. Every object has an overridableEquals
method. You can simply overwrite that. Be careful when you implement your own comparison method. Your implementation shown in this sample is very open to NullReference exceptions. Something like this would be better:正如其他人提到的,如果您走这条路线并覆盖
Equals
,您也应该覆盖GetHashCode
。您还应该考虑其他一些事情。有关详细信息,请参阅此 MSDN 页面。You updated
fooInstance1
twice there. Second line should sayfooInstance2.fooField1 = 5;
.Once that's fixed,
Q.Contains
returnsTrue
as expected.Other than that, you don't necessarily need to implement
IEquatable
. Every object has an overridableEquals
method. You can simply overwrite that. Be careful when you implement your own comparison method. Your implementation shown in this sample is very open to NullReference exceptions. Something like this would be better:As others have mentioned, if you go this route and override
Equals
, you should overrideGetHashCode
, too. There are a few other things you should consider. See this MSDN page for details.为什么它很重要在 C# 中重写 Equals 方法时重写 GetHashCode?
Why is it important to override GetHashCode when Equals method is overriden in C#?
一旦初始编译错误得到解决,您的示例代码就会按预期工作。并不是说它与所提出的问题相关,请阅读有关重写 Equals 的内容(您也需要重写 GetHashCode 并检查 null / 类型不匹配等错误情况)。
Your sample code works as expected once the initial compile errors are sorted out. Not that it is relevant to the posed problem, Do read up on overriding Equals (you need to override GetHashCode too and check for error cases like null / type-mismatch).