C# 在C中创建GetHashCode方法#

C# 在C中创建GetHashCode方法#,c#,.net,hashcode,gethashcode,C#,.net,Hashcode,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); } p

为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() ;
}

或者我应该做些别的吗?

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

要实现
GetHashCode
,请参阅

要实现
等于
,请使用扩展方法

编辑:在.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;
}
publicstaticboolsequenceequals(第一个IList,第二个IList){
if(first==second)返回true;
if(first==null | | second==null)返回false;
if(first.Count!=second.Count)返回false;
for(int i=0;i

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

确保.GetHashCode()的重写与.Equals()同步非常重要

基本上,你必须确保他们考虑相同的字段,以免违反GetHashCode(from)

的三条规则中的第一条规则。 如果两个对象比较相等,则 每个对象的GetHashCode方法 必须返回相同的值。然而, 如果两个对象不进行比较 equal,用于 两个对象不必返回 不同的价值观

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

正如这里其他人提到的,详细说明了一个好的实现。
如果你感兴趣的话,我在去年年初写了几篇关于研究散列码的博客文章。你可以找到我的漫谈(我写的第一篇关于这个主题的博客)

关于这些问题有很好的讨论,最近的更新提到了SharpArchitecture提供的


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

如果你使用dotnetcore 2.1+,你可以对所有属性使用struct的
Combile
方法,这非常容易使用和高效。

你在这里没有正确覆盖Equals。实际上,我认为这会导致堆栈溢出。不,它不会溢出堆栈。不过,这也行不通。这已经让他陷入了stackoverflow。感谢您的快速回复。是否有一种可用于.NET framework 2.0的SequenceEqual替代方案?