IEquatable,如何正确实施
我正在使用 .net 2.0 和 c#,并且我已经在我的类中实现了 IEquatible 接口,如下所示:-
public MyClass() : IEquatable<MyClass>
{
Guid m_id = Guid.NewGuid();
public Guid Id
{
get
{
return m_id;
}
}
#region IEquatable<MyClass> Members
public bool Equals(MyClass other)
{
if (this.Id == other.Id)
{
return true;
}
else
{
return false;
}
}
#endregion
}
这是不好的编程习惯吗?我读到我还需要实现 Object.Equals 和 Object.GetHashCode ,但我不确定为什么。
我希望能够检查 MyClass 的实例是否已包含在 MyClass 类型的通用列表中。为什么框架只建议您仅实现 Equals?
任何帮助将不胜感激。
I am using .net 2.0 and c# and I have implemented the IEquatible interface in my class like this:-
public MyClass() : IEquatable<MyClass>
{
Guid m_id = Guid.NewGuid();
public Guid Id
{
get
{
return m_id;
}
}
#region IEquatable<MyClass> Members
public bool Equals(MyClass other)
{
if (this.Id == other.Id)
{
return true;
}
else
{
return false;
}
}
#endregion
}
Is this bad programming practice? I've read that I also need to implement Object.Equals and Object.GetHashCode as well, but I am not sure why.
I want to be able to check that an instance of MyClass is not already contained in a generic list of type MyClass. Why does the framework only suggests that you implement Equals only?
Any help would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 LINQ 检查您的列表是否包含使用自定义谓词作为条件的项目。在这种情况下,您不需要重写
Equals
也不需要实现IEquatable
:重写
Equals
(使用GetHashCode
)并且如果您需要将项目存储在Dictionary
或Hashtable
中,那么实现IEquatable
会非常有用。You can check if your list contains an item using a custom predicate for the criteria, using LINQ. In that case you don't need to override
Equals
nor implementIEquatable
:Overriding
Equals
(withGetHashCode
) and implementingIEquatable
is useful if you need to store your item in aDictionary
or aHashtable
.实现 IEquatable非常棒,对于结构体来说更是如此,但仅仅做到这么多还不够。
在这里阅读为什么..
在此处阅读并<一href="https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java">此处。说真的,这些已经讨论过很多次了,而且非常简单。简而言之,您需要它来处理诸如
Dictionary<,>
或HashSet<> 等哈希值的集合类型;
取决于集合类型。对于
List
,它将仅根据您定义的Equals
方法(例如Contains
方法)来检查相等性。对于大多数情况,您只需要Equals
。但是,如果您有一个HashSet
,则缺席和存在检查将利用对象的哈希值。框架确实要求我们实现良好的哈希方法(无需重新发明轮子)在适当的地方。执行如下操作,但仅当对您有意义时才必须重载运算符
==
和!=
。看到你的类,我认为你的类可以具有值语义。否则,只需忽略该部分(如果==
应该意味着引用相等)...从您的 guid 获取哈希码就足够了,前提是您需要测试相等性。为了避免出错,请使用此处提供的代码段:以获得良好的概述< a href="https://stackoverflow.com/questions/104158/what-is-best-practice-for-comparing-two-instances-of-a-reference-type">请参阅此线程。
Implementing
IEquatable<T>
is great, even more so for structs, but merely doing that much is not enough.Read it here why..
Read it here and here. Seriously, these have been discussed so many times, and it is pretty simple.. In short, you need it for collection types that deals with hashes like
Dictionary<,>
orHashSet<>
Depends on the collection type. For a
List<T>
, it will check equality merely based on how you have definedEquals
method, say forContains
method. For most scenario you will needEquals
only. But if you have aHashSet<T>
then absence and presence checks will utilize hash of your objects. Framework indeed asks us to implement good hashing approaches (without re-inventing the wheel) at appropriate places.Do as below, but you have to overload operators
==
and!=
only if it make sense to you. Seeing your class I assumed its ok to have value semantics for your class. Otherwise just ignore that part (if==
should mean reference equality)... Getting hashcode from your guid would suffice, provided that is all you need to test equality.To not get it wrong, make use of the snippet available here: For a good overview see this SO thread.