2016-01-06 116 views
1

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

我知道从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; 
     } 
    } 
} 

回答

4

DispositionInfo不具有覆盖GetHashCode()一个类型。两个具有相同对象的相同字典将具有不同的哈希码。

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

+0

啊!这就说得通了! * Smacks头对着办公桌* – JNYRanger

+0

我会更倾向于排除字典,GetHashCode应该是一个快速返回的函数,如果大的话可能会很慢,通过整个字典。 –

+0

它很少会有超过20个键值对,但我需要包含它,因为我使用它来确保没有任何变化(包括字典中的键值对)是使用哈希码的目的。对它进行序列化并生成一个SHA-1哈希值就是个诀窍。不是性能最快的方法,但速度足以满足其使用目的。 – JNYRanger

1

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

此行为非常重要,因为如果您使用散列作为引用对象的方式,更改其任何值都将导致无法再次引用。

如果您想要具有相同字段的对象具有相同散列码的行为,则需要自行实施。

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

+0

我提到的不正确倍率的全部内容。他指的编辑前的响应。 – SaxxonPike

+0

@SaxxonPike看见你固定它,删除了我的评论/ downvote – JNYRanger