.net 使用recordId作为哈希代码是个坏主意吗?

.net 使用recordId作为哈希代码是个坏主意吗?,.net,hash,.net,Hash,假设我有一个数据库外的简单DTO对象,Id是一个绝对唯一的recordId,那么执行以下操作是一个好主意吗 public class DTO { public int Id { get; set; } public override bool Equals(object obj) { return (Id == ((DTO)obj).Id); } public override int GetHashCode() {

假设我有一个数据库外的简单DTO对象,Id是一个绝对唯一的
recordId
,那么执行以下操作是一个好主意吗

public class DTO
{
    public int Id { get; set; }

    public override bool Equals(object obj)
    {
        return (Id == ((DTO)obj).Id);
    }

    public override int GetHashCode()
    {
        return Id;
    }
}
我有点怀疑它的原因是因为我在我周围的代码中看不到它,而不是像这样的代码

int hash = 7;
hash = 89 * hash + pageId.hashCode();
hash = 89 * hash + recordId;
return hash;

哈希代码的约定是“两个相等的对象必须具有相同的哈希代码”。这意味着用于确定相等性的任何字段都必须用构成哈希代码的位表示。由于您的相等约定仅引用
ID
,因此这是哈希代码中唯一需要的内容。

一个好的哈希函数应该(或多或少)随机分配哈希值,因此当您将哈希值放入二叉树时,您会得到一个好的、均匀分布的树,而不是一个只在一边的链表

请看这里:


但是,如果您从来没有这种需要(即,您总是从数据库返回记录,而不是从您自己的二叉树中查找记录),那么使用id作为哈希对我来说似乎是完全合理的。

因为int已经有了获取哈希代码的方法,所以我只会使用该方法

public override int GetHashCode()
{
    return Id.GetHashCode();
}

如果您的类只包含一个整数,则可以将其用作哈希代码。这与只返回整数本身的
Int32.GetHashCode
方法的实现相同。

这意味着用于确定相等性的任何字段都必须用构成哈希代码的位表示。-->依我看,这不是事实,这可能是最好的,但没有必要履行合同。如果hashcode为return23;例如,两个相等的对象将具有相同的哈希代码,因为您的注释对我来说没有任何意义。你说“没有必要遵守合同”,然后给出一个hashcode函数返回常量的例子,作为某件事情的“例子”。但这是一个什么样的例子呢?尽管出于其他原因,它只是一个蹩脚的散列函数,但它基本上遵守了合同。是的,两个相等的对象必须具有相同的哈希代码;这不取决于意见。(否则,两个相等的对象可能会在同一组中结束,或作为同一地图中的键。)如果你引用错了我的话,请仔细阅读:1。当然,履行合同是必要的。2.两个相等的对象必须具有相同的散列码,当然,我不是在另外说明3。我只是说,为了履行合同,不需要使用构成相等的字段。对不起,这完全是错误的。回答你的问题“这是什么的一个例子”:这是一个蹩脚的hashfunction的例子,但证明了一个hashfunction不需要使用平等使用的字段来履行合同。我将你的陈述解释为“在我看来,这不是真的,这可能是最好的,但没有必要履行合同。”“没有必要遵守合同”,我认为这是对这句话的合理解释(尽管令人困惑!)。我现在明白你的意思是“为了遵守合同,在哈希函数中使用平等检查中涉及的所有字段是不必要的。”所以现在我也理解了你的“示例”"!你为什么要这样做呢?不管怎样,这不只是再次返回int吗?我只使用int就可以得到完美(100%)的分布,为什么要散列int呢?我相信这只是出于完美分布的相同原因再次返回int。如果总是加载所有实体,这可能是完美分布,但如果只加载子集,则该子集可能没有均匀分布的ID。请参阅文章。唯一的问题是,如果将表中的记录按数字顺序放入字典(或其他二进制搜索结构),那么将使索引倾斜。@iammichal:我不相信我能理解,每个存储桶每个定义只有一个元素,不管是哪一个子集,解决方案都是使用自平衡的数据结构(如红黑树),或者将记录以随机顺序放入结构中。但是,如果你不需要这个,这都是学术性的。我只是指出这一点,因为你问了,这是我能想到为什么int作为散列可能不是一个好主意的唯一原因。事实上,我也这么认为,请参阅前面的评论,TXS因为它是DTO,也会有其他字段,但数据库会保证int是唯一的。嗯。。。事实上,我目前正在与一个类似的问题作斗争。FWIW,我认为使用如上所述的ID属性的精确定义(即使用公共setter),它不能安全地用作GetHashCode()的属性。对象哈希代码的一个特点是,在创建对象实例后,它不能更改。所以,Id确实应该通过构造函数设置,并且没有公共setter。我同意,它是一个过于简单的类