Note that there are some explanatory texts on larger screens.

plurals
  1. POOverriding GetHashCode for mutable objects?
    primarykey
    data
    text
    <p>I've read about 10 different questions on when and how to override <code>GetHashCode</code> but there's still something I don't quite get. Most implementations of <code>GetHashCode</code> are based on the hash codes of the fields of the object, but it's been cited that the value of <code>GetHashCode</code> should never change over the lifetime of the object. How does that work if the fields that it's based on are mutable? Also what if I do want dictionary lookups etc to be based on reference equality not my overridden <code>Equals</code>? </p> <p>I'm primarily overriding <code>Equals</code> for the ease of unit testing my serialization code which I assume serializing and deserializing (to XML in my case) kills the reference equality so I want to make sure at least it's correct by value equality. Is this bad practice to override <code>Equals</code> in this case? Basically in most of the executing code I want reference equality and I always use <code>==</code> and I'm not overriding that. Should I just create a new method <code>ValueEquals</code> or something instead of overriding <code>Equals</code>? I used to assume that the framework always uses <code>==</code> and not <code>Equals</code> to compare things and so I thought it was safe to override <code>Equals</code> since it seemed to me like its purpose was for if you want to have a 2nd definition of equality that's different from the <code>==</code> operator. From reading several other questions though it seems that's not the case.</p> <p><strong>EDIT:</strong></p> <p>It seems my intentions were unclear, what I mean is that 99% of the time I want plain old reference equality, default behavior, no surprises. For very rare cases I want to have value equality, and I want to explicitly request value equality by using <code>.Equals</code> instead of <code>==</code>. </p> <p>When I do this the compiler recommends I override <code>GetHashCode</code> as well, and that's how this question came up. It seemed like there's contradicting goals for <code>GetHashCode</code> when applied to mutable objects, those being:</p> <ol> <li>If <code>a.Equals(b)</code> then <code>a.GetHashCode()</code> should <code>== b.GetHashCode()</code>.</li> <li>The value of <code>a.GetHashCode()</code> should never change for the lifetime of <code>a</code>.</li> </ol> <p>These seem naturally contradicting when a mutable object, because if the state of the object changes, we expect the value of <code>.Equals()</code> to change, which means that <code>GetHashCode</code> should change to match the change in <code>.Equals()</code>, but <code>GetHashCode</code> should not change.</p> <p>Why does there seem to be this contradiction? Are these recommendations not meant to apply to mutable objects? Probably assumed, but might be worth mentioning I'm referring to classes not structs.</p> <p><strong>Resolution:</strong></p> <p>I'm marking JaredPar as accepted, but mainly for the comments interaction. To sum up what I've learned from this is that the only way to achieve all goals and to avoid possible quirky behavior in edge cases is to only override <code>Equals</code> and <code>GetHashCode</code> based on immutable fields, or implement <code>IEquatable</code>. This kind of seems to diminish the usefulness of overriding <code>Equals</code> for reference types, as from what I've seen most reference types usually have no immutable fields unless they're stored in a relational database to identify them with their primary keys.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload