在 C# 中创建 GetHashCode 方法
在 C# 中为类创建自己的 GetHashCode 方法的最佳方法是什么? 假设我有一个简单的类(它重写了 Equals 方法),如下所示:
class Test
{
public string[] names;
public double[] values;
public override bool Equals(object obj)
{
return (obj is Test) && this.Equals((Test)obj);
}
public bool Equals(Test t)
{
return names.Equals(t.names) && values.Equals(t.values);
}
}
我应该使用 GetHashCode 方法的默认代码吗?
public override int GetHashCode()
{
return base.GetHashCode();
}
我应该根据我的课程内容来制定方法吗?
public override int GetHashCode()
{
return names.GetHashCode() + values.GetHashCode() ;
}
或者我应该做点别的什么?
What is the best way to create your own GetHashCode method for a class in C#? Suppose I have a simple class (which overrides the Equals method), as follows:
class Test
{
public string[] names;
public double[] values;
public override bool Equals(object obj)
{
return (obj is Test) && this.Equals((Test)obj);
}
public bool Equals(Test t)
{
return names.Equals(t.names) && values.Equals(t.values);
}
}
Should I use the default code for the GetHashCode method?
public override int GetHashCode()
{
return base.GetHashCode();
}
Should I base the method on the contents of my class?
public override int GetHashCode()
{
return names.GetHashCode() + values.GetHashCode() ;
}
Or should I do something else?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
System.Array
不会覆盖GetHashCode
或Equals
,因此它们使用引用相等。 因此,您不应该给他们打电话。要实现
GetHashCode
,请参阅要实现
Equals
,请使用SequenceEqual
扩展方法。编辑:在.Net 2.0上,您必须编写自己的
SequenceEqual
版本,如下所示:您可以将其编写为采用
IEnumerable< /code> 而不是
IList
,但速度会慢一些,因为如果参数大小不同,它将无法提前退出。System.Array
does not overrideGetHashCode
orEquals
, so they use reference equality. Therefore, you shouldn't call them.To implement
GetHashCode
, see this question.To implement
Equals
, use theSequenceEqual
extension method.EDIT: On .Net 2.0, you'll have to write your own version of
SequenceEqual
, like this:You could write it to take
IEnumerable<T>
instead ofIList<T>
, but it'd be somewhat slower because it wouldn't be able to exit early if the parameters have different sizes.确保将 .GetHashCode() 重写与 .Equals() 保持同步非常重要。
基本上,您必须确保它们考虑相同的字段,以免违反 GetHashCode 的三个规则中的第一个(来自 MSDN 对象.GetHashCode())
换句话说,您必须确保每次 .Equals 认为两个实例相等时,它们也将具有相同的 .GetHashCode()。
正如这里其他人提到的,这个问题< /a> 详细介绍了一个很好的实现。
如果您有兴趣,我去年年初写了一些关于研究哈希码的博客文章。 您可以在此处找到我的漫谈(我就此主题撰写的第一篇博客文章)
It is really important to make sure you keep the override of .GetHashCode() in step with .Equals().
Basically, you must make sure they consider the same fields so as not to violate the first of the three rules of GetHashCode (from MSDN object.GetHashCode())
In other words, you must make sure that every time .Equals considers two instances equal, they will also have the same .GetHashCode().
As mentioned by someone else here, this question details a good implementation.
In case you are interested, I wrote up a few blog articles on investigating hash codes early last year. You can find my ramblings here (the first blog entry I wrote on the subject)
这里对这些问题进行了很好的讨论,最新更新是指 SharpArchitecture 提供的 BaseObject 抽象类。
如果您想要更多临时,我发现 ReSharper 为 Equals() 和 GetHashCode() 生成的代码很好。
There's a good discussion of the issues here, and the most recent update refers to the BaseObject abstract class provided by SharpArchitecture.
If you want something more ad hoc, I've found that the code that ReSharper generates for Equals() and GetHashCode() is fine.
如果您使用 dotnetcore 2.1+,则可以使用 HashCode结构体的
Combile
方法可以对所有属性进行组合,使用起来非常方便,效率也很高。If you use dotnetcore 2.1+, you can use HashCode struct's
Combile
method to all properties, it's very easily to use and efficiency.