GetHashCode()为相同的对象值返回不同的值

时间:2016-01-06 16:27:24

标签: c# asp.net asp.net-mvc hash hashcode

在尝试通过ASP.NET MVC应用程序中的ajax调用验证对象是否已更改时,我尝试使用GetHashCode()值。但是,我注意到这不起作用,因为验证期间返回的哈希码值与在验证请求之后从另一个请求中的模型绑定再次创建对象时生成的哈希码不同。我能够通过创建SHA哈希来解决这个问题,但我很好奇为什么我会看到这种行为。

我知道从GetHashCode()生成的哈希码不应该保留,并且可能会因不同平台和时间而有所不同。当我第一次提出这个想法时,我认为时间段足够短,因为这两个调用是以毫秒为单位进行的,并且在调试时我确认模型包含完全相同的值,但仍然产生了不同的哈希码。

我很好奇为什么会出现这种行为。为什么会发生这种情况,即使这是应用程序的单次运行,尽管是Web应用程序?这与ASP.NET生命周期有关吗?

如果需要这里的课程&我正在使用的GetHashCode实现:

class DispositionSubmission
{
    [Display(Name = "Client")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Client is required.")]
    public string ClientId { get; set; }
    public string Carrier { get; set; }
    public Dictionary<string, string> DispositionInfo { get; set; }
    public DispositionType Type { get; set; } //int based enum

...

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = (int)15485863;
            int bigPrime = (int)15485867;

            hash = hash * bigPrime ^ ClientId.GetHashCode();
            hash = hash * bigPrime ^ (Carrier ?? "").GetHashCode();
            hash = hash * bigPrime ^ DispositionInfo.GetHashCode();
            hash = hash * bigPrime ^ Type.GetHashCode();

            return hash;
        }
    }
}

2 个答案:

答案 0 :(得分:5)

DispositionInfo没有覆盖GetHashCode()的类型。其中包含相同对象的两个相同的词典将具有不同的哈希码。

您需要将GetHashCode()调整为不包含字典或使其更复杂,以获取字典中每个键和值的哈希码并将其添加。

答案 1 :(得分:1)

GetHashCode将为完全相同的对象返回相同的结果。如果已重新分配对象,则在所有字段中具有相同的值并不重要,您将得到不同的结果。这是因为你真正使用的是Object.GetHashCode(),它对其他领域一无所知。

此行为很重要,因为如果您使用哈希作为引用对象的方式,则更改其任何值将导致无法再次引用。

如果您希望具有相同字段的对象具有相同哈希码的行为,则需要自己实现它。

编辑:澄清:DispositionInfo,字典,具体表现出这种行为。其他字段没有,因为它们被设计为不可变的(字符串,整数等)。考虑以不同的方式获取哈希,或者使用从GetHashCode继承的自定义类覆盖Dictionary<string, string>。 / p>