在 C# 中创建 GetHashCode 方法

发布于 2024-07-27 18:41:38 字数 703 浏览 9 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤星 2024-08-03 18:41:38

System.Array 不会覆盖 GetHashCodeEquals,因此它们使用引用相等。 因此,您不应该给他们打电话。

要实现 GetHashCode,请参阅

要实现Equals,请使用SequenceEqual 扩展方法。

编辑:在.Net 2.0上,您必须编写自己的SequenceEqual版本,如下所示:

public static bool SequenceEquals<T>(IList<T> first, IList<T> second) {
    if (first == second) return true;
    if (first == null || second == null) return false;

    if (first.Count != second.Count) return false;

    for (int i = 0; i < first.Count; i++)
        if (!first[i].Equals(second[i]))
            return false;

    return true;
}

您可以将其编写为采用IEnumerable< /code> 而不是 IList,但速度会慢一些,因为如果参数大小不同,它将无法提前退出。

System.Array does not override GetHashCode or Equals, so they use reference equality. Therefore, you shouldn't call them.

To implement GetHashCode, see this question.

To implement Equals, use the SequenceEqual extension method.

EDIT: On .Net 2.0, you'll have to write your own version of SequenceEqual, like this:

public static bool SequenceEquals<T>(IList<T> first, IList<T> second) {
    if (first == second) return true;
    if (first == null || second == null) return false;

    if (first.Count != second.Count) return false;

    for (int i = 0; i < first.Count; i++)
        if (!first[i].Equals(second[i]))
            return false;

    return true;
}

You could write it to take IEnumerable<T> instead of IList<T>, but it'd be somewhat slower because it wouldn't be able to exit early if the parameters have different sizes.

み青杉依旧 2024-08-03 18:41:38

确保将 .GetHashCode() 重写与 .Equals() 保持同步非常重要。

基本上,您必须确保它们考虑相同的字段,以免违反 GetHashCode 的三个规则中的第一个(来自 MSDN 对象.GetHashCode())

如果两个对象比较相等,则
每个对象的 GetHashCode 方法
必须返回相同的值。 然而,
如果两个对象不比较
等于,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())

If two objects compare as equal, the
GetHashCode method for each object
must return the same value. However,
if two objects do not compare as
equal, the GetHashCode methods for the
two object do not have to return
different values.

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)

云仙小弟 2024-08-03 18:41:38

这里对这些问题进行了很好的讨论,最新更新是指 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.

凉风有信 2024-08-03 18:41:38

如果您使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文