简体   繁体   English

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

[英]GetHashCode() Returning Different Values For Identical Object Values

I was attempting to use the GetHashCode() value to determine if an object has changed after it's been validated via ajax calls in an ASP.NET MVC application. 我试图使用GetHashCode()值来确定在通过ASP.NET MVC应用程序中的Ajax调用验证了对象之后是否更改了对象。 However, I noticed that this did not work because the hash code value when returned during validation would be different than the hash code generated when the object was created again from the model binding with the same values in another request after the validation request. 但是,我注意到这是行不通的,因为在验证期间返回的哈希码值将不同于在验证请求之后另一个请求中从模型绑定中使用相同值再次通过模型绑定创建对象时生成的哈希码。 I was able to solve this problem by creating a SHA hash instead, but I'm curious on why I was seeing this behavior. 我可以通过创建SHA哈希来解决此问题,但是我很好奇为什么看到这种行为。

I know that hash codes generated from GetHashCode() should not be persisted and can differ on different platforms and over time. 我知道从GetHashCode()生成的哈希码不应该保留,并且在不同的平台上可能会有所不同。 I thought that the time period was short enough when I first came up with this idea since these two calls were made in milliseconds of each other and when debugging I confirmed that the model contained the exact same values, but still produced a different hash code. 我以为,当我第一次提出这个主意时,时间就足够短了,因为这两个调用之间的间隔是毫秒,调试时,我确认该模型包含了完全相同的值,但是仍然产生了不同的哈希码。

I'm curious about why this behavior is exhibited. 我很好奇为什么会表现出这种行为。 Why would this happen even though this is a single run of the application, albeit a web application? 即使是Web应用程序,即使这是应用程序的单次运行,为什么还会发生这种情况? Does this have to do with the ASP.NET life cycle? 这与ASP.NET生命周期有关吗?

In case needed here's the class & GetHashCode implementation I was using: 如果需要,这里是我正在使用的类和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;
        }
    }
}

DispositionInfo does not have a type that overrides GetHashCode() . DispositionInfo没有重写GetHashCode()的类型。 Two identical dictionaries with the same objects in them will have different hash codes. 其中具有相同对象的两个相同字典将具有不同的哈希码。

You will need to adjust your GetHashCode() to either not include the dictionary or make it more complex to get the hash code of each key and value in the dictionary and add them up. 您将需要调整GetHashCode()使其不包括字典,或者使其变得更加复杂,以获取字典中每个键和值的哈希码并将它们加起来。

GetHashCode will return the same result for the exact same object. GetHashCode将为完全相同的对象返回相同的结果。 If the object has been reallocated, it doesn't matter if you have identical values in all fields, you will get a different result. 如果已重新分配对象,则在所有字段中都具有相同的值并不重要,您将获得不同的结果。 This is because what you're really using is Object.GetHashCode() , which knows nothing about its other fields anyway. 这是因为您真正使用的是Object.GetHashCode() ,但对其他字段一无所知。

This behavior is important because if you're using the hash as a way to refer to the object, changing any of its values would make it impossible to reference again. 此行为很重要,因为如果您使用哈希作为引用该对象的方式,则更改其任何值都将使其无法再次引用。

If you want to have behavior where objects with identical fields have the same hash code, you'll need to implement it yourself. 如果您希望具有相同字段的对象具有相同哈希码的行为,则需要自己实现。

Edit: To clarify: DispositionInfo , the dictionary, specifically exhibits this behavior. 编辑:澄清:字典DispositionInfo专门表现出此行为。 The other fields do not, because they are designed to be immutable (string, int, etc.) Consider getting the hash a different way, or overriding GetHashCode with a custom class that inherits from Dictionary<string, string> . 其他字段则不是,因为它们被设计为不可变的(字符串,整数等)。请考虑以其他方式获取哈希,或使用继承自Dictionary<string, string>的自定义类覆盖GetHashCode

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM