关于c#:重写GetHashCode

Overriding GetHashCode

本问题已经有最佳答案,请猛点这里访问。

如您所知,GetHashCode返回一个半唯一值,该值可用于标识集合中的对象实例。作为一个好的实践,建议重写此方法并实现自己的方法。

我的问题是-在处理自定义对象时是否重写此方法?如果是,您使用什么算法来生成唯一的ID?

我正在考虑生成一个guid,然后从那个标识符中获取整数数据。


如果使用resharper,它可以为您生成gethashcode()、equals和operator方法体。

alt+insertakbd可访问此菜单。

http://www.jetbrains.com/resharper/webhelp/code_u generation_uu equality_members.html


当您覆盖GetHashCode()时,您还需要覆盖Equals()operator==operator!=。并且要非常小心地满足这些方法的所有要求。

本指南在MSDN上。最重要的引用:

It is not a good idea to override operator == in non-immutable types.


我通常会重写数据类(即值语义有意义的类)的哈希代码和相等性检查方法。请看一看这个问题以获得一个通用的实现。如果您确实重写了hashcode,则重写等于。使用一个guid是一个非常糟糕的想法,因为您希望两个不同实例但具有相同值的对象具有相同的哈希代码,而for equals返回true。


在我的个人用法中,我只在重写equals方法时重写。通常,我会为我知道可以对其运行linq-to-objects查询或其他比较操作的对象执行此操作。

如果说linq to sql实体或dto对象,我通常返回主键值。无论返回什么,如果不在本地存储该值,它可能会产生意外的结果。

Hth.


仅当重写equals时才需要重写gethashcode。默认的gethashcode由运行时以您希望的类似方式实现-每个对象都有一个由运行时分配的隐藏字段。

如何重写GetHashCode

实际上,您的IDE应该为您这样做——当您键入"override gethashcode"时,IDE应该生成这个样板代码。Visual Studio不执行此操作,但SharpDevelop执行此操作。


通常,我使用类的组件属性中的聚合GetHashCode。例如。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test
{
  public string Text { get; set; }
  public int Age { get; set; }

  public override GetHashCode()
  {
    int result =
      string.IsNullOrEmpty(Text) ? 0 : Text.GetHashCode()
      + Age.GetHashCode();

    return result;
  }
}