在 C# 中创建 GetHashCode 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1166135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:48:47  来源:igfitidea点击:

Creating the GetHashCode method in C#

c#.nethashcodegethashcode

提问by Richie Cotton

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:

在 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);
   }
}

Should I use the default code for the GetHashCode method?

我应该使用 GetHashCode 方法的默认代码吗?

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?

还是我应该做点别的?

采纳答案by SLaks

System.Arraydoes not override GetHashCodeor Equals, so they use reference equality. Therefore, you shouldn't call them.

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

To implement GetHashCode, see this question.

要实施GetHashCode,请参阅此问题

To implement Equals, use the SequenceEqualextension method.

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

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

编辑:在 .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;
}

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.

您可以将其编写为 takeIEnumerable<T>而不是IList<T>,但它会稍微慢一些,因为如果参数具有不同的大小,它将无法提前退出。

回答by Rob Levine

It is really important to make sure you keep the override of .GetHashCode() in stepwith .Equals().

以确保您保持.GetHashCode()的覆盖它是非常重要的步骤与.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())

基本上,您必须确保它们考虑相同的字段,以免违反 GetHashCode 的三个规则中的第一个(来自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.

如果两个对象比较相等,则每个对象的 GetHashCode 方法必须返回相同的值。但是,如果两个对象不相等,则两个对象的 GetHashCode 方法不必返回不同的值。

In other words, you must make sure that every time .Equals considers two instances equal, they will also have the same .GetHashCode().

换句话说,您必须确保每次 .Equals 认为两个实例相等时,它们也将具有相同的 .GetHashCode()。

As mentioned by someone else here, this questiondetails 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)

正如这里的其他人所提到的,这个问题详细说明了一个很好的实现。如果您有兴趣,我在去年年初写了几篇关于调查哈希码的博客文章。你可以在这里找到我的散文(我写的第一篇关于这个主题的博客文章)

回答by Dave W

There's a good discussion of the issues here, and the most recent update refers to the BaseObject abstract classprovided by SharpArchitecture.

还有的问题商量好了这里,和最新的更新是指BaseObject抽象类的SharpArchitecture提供。

If you want something more ad hoc, I've found that the code that ReSharper generates for Equals() and GetHashCode() is fine.

如果您想要更特别的东西,我发现 ReSharper 为 Equals() 和 GetHashCode() 生成的代码很好。

回答by Jeffrey Hill

If you use dotnetcore 2.1+, you can use HashCodestruct's Combilemethod to all properties, it's very easily to use and efficiency.

如果使用 dotnetcore 2.1+,则可以对所有属性使用HashCode结构体的Combile方法,使用起来非常方便,效率也很高。