简体   繁体   中英

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. 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.

I know that hash codes generated from GetHashCode() should not be persisted and can differ on different platforms and over time. 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? Does this have to do with the ASP.NET life cycle?

In case needed here's the class & GetHashCode implementation I was using:

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() . 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 will return the same result for the exact same object. 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.

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. 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> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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