实体类的GetHashCode()的正确实现是什么?

Jos*_*off 15 .net c# orm

下面是覆盖实体基类的Object.Equals()的示例实现,应用程序中的所有其他实体都从该实体基类派生.

所有实体类都具有属性Id,它是一个可以为null的int.(它是实体类对应的任何表的主键.)

public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
                return false;

            if (base.Equals(obj))
                return true;

            return Id.HasValue && ((EntityBase) obj).Id.HasValue &&
                   Id.Value == ((EntityBase) obj).Id.Value;
        }
Run Code Online (Sandbox Code Playgroud)

鉴于Equals()的这种实现,你如何正确实现GetHashCode()?

Jon*_*eet 23

如果你是从已经覆盖的东西中得到的,那么GetHashCode我将它实现为:

public override int GetHashCode()
{
    unchecked
    {
        int hash = 37;
        hash = hash * 23 + base.GetHashCode();
        hash = hash * 23 + Id.GetHashCode();
        return hash;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于Id.GetHashCode(),Id的空值将返回0.

如果你的类只是派生自Object,我只是返回Id.GetHashCode()- 你希望object.GetHashCode在哈希代码中包含实现,因为它基本上最终成为对象标识.

请注意,如果两个实体都没有Id,则不会返回等式定义true,但是将从两个对象返回相同的哈希码.您可能希望考虑更改您的Equals实施.

  • 对于那些想知道的人,就像我一样:23和37是任意数字,是共同素数.乔恩在这里用类似的答案说:http://www.eggheadcafe.com/software/aspnet/29483139/override-gethashcode.aspx (9认同)