<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx</link><description>" The code is more what you'd call guidelines than actual rules " - truer words were never spoken. It's important when writing code to understand what are vague "guidelines" that should be followed but can be broken or fudged, and what are crisp "rules</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10328396</link><pubDate>Tue, 10 Jul 2012 15:55:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10328396</guid><dc:creator>Martijn</dc:creator><description>&lt;p&gt;Thank you very much for this post, which was pointed out to me on stackoverflow: &lt;a rel="nofollow" target="_new" href="http://stackoverflow.com/questions/11410994/hashsets-dont-keep-the-elements-unique-if-you-mutate-their-identity/11411100#comment15057479_11411100"&gt;stackoverflow.com/.../11411100&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The collary of&lt;/p&gt;
&lt;p&gt;&amp;quot;Rule: the integer returned by GetHashCode must never change while the object is contained in a data structure that depends on the hash code remaining stable&amp;quot; (thus, Equality comparison should never change while the object is contained in a datastructure that depends on equality - but other analogies also might be appropriate), I came up with the following rule (which is in fact more-or-less equal to the above rule.):&lt;/p&gt;
&lt;p&gt;&amp;quot;GetHashCode should never depend on values that are mutable&amp;quot;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10328396" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10161975</link><pubDate>Fri, 06 May 2011 22:25:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10161975</guid><dc:creator>Marc Brooks</dc:creator><description>&lt;p&gt;Oliver, yes, I reported that bug here: &lt;a rel="nofollow" target="_new" href="http://bit.ly/aSkUIm"&gt;http://bit.ly/aSkUIm&lt;/a&gt; (and as usual, Microsoft decided to close as Won&amp;#39;t Fix)&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve written extensively about hashing here: &lt;a rel="nofollow" target="_new" href="http://bit.ly/9qNcga"&gt;http://bit.ly/9qNcga&lt;/a&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10161975" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10136695</link><pubDate>Thu, 03 Mar 2011 23:24:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136695</guid><dc:creator>Pavel Minaev [MSFT]</dc:creator><description>&lt;p&gt;Oh, and here&amp;#39;s one more very good reason why you should always override Equals and GetHashCode on your structs in practice:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="https://connect.microsoft.com/VisualStudio/feedback/details/374654/valuetype-equals-is-incorrect#details"&gt;connect.microsoft.com/.../valuetype-equals-is-incorrect&lt;/a&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136695" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10136694</link><pubDate>Thu, 03 Mar 2011 23:21:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136694</guid><dc:creator>Pavel Minaev [MSFT]</dc:creator><description>&lt;p&gt;&amp;gt;&amp;gt; What makes you think a fully general implementation of this could be more efficient than it is?&lt;/p&gt;
&lt;p&gt;Given that ValueType is one of the &amp;quot;magical&amp;quot; CLR types about which the runtime has special knowledge, it&amp;#39;s quite possible - for example, the runtime could detect that your struct does not override Equals/GetHashCode, and generate its own (separately for every struct) that accesses fields directly.&lt;/p&gt;
&lt;p&gt;&amp;gt;&amp;gt; Likewise for strings, &amp;quot;a&amp;quot; and &amp;quot;a&amp;quot; should be equal (even though the object ref may not be) - Tuple, String, Uri and XName, I see. &amp;nbsp;I think then you could say that you ought to implement GetHashCode when you want the Equals() operator to be a logical Equals and not a ReferenceEquals? &amp;nbsp;is that a fair characterization?&lt;/p&gt;
&lt;p&gt;Pretty much, yes. Equals and GetHashCode always go hand in hand - if you&amp;#39;re not overriding Equals, the default GetHashCode is good as it is. If I remember correctly, C# compiler will even warn if you override one but not the other.&lt;/p&gt;
&lt;p&gt;Ultimately, the point is that for all those types like String, reference equality is mostly meaningless since you don&amp;#39;t derive anything useful out of knowing whether it is the same object or not. Hence why you&amp;#39;d want to default to value comparisons. If anyone actually does care about object identity (e.g. for strings, this is sometimes used as an optimization, either with interning or with a local symbol table, like XmlNameTable in System.Xml), they can always use Object.ReferenceEqual.&lt;/p&gt;
&lt;p&gt;Usually, for those kinds of types, operator== is also overloaded: out of those listed, for String this is done on language level, Uri and XName actually do overload it, and Tuple doesn&amp;#39;t overload it because there is no clear way to propagate language-dependent equality semantics of tuple components (which can differ e.g. between C#/VB).&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136694" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10136626</link><pubDate>Thu, 03 Mar 2011 21:26:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136626</guid><dc:creator>Alex Lo</dc:creator><description>&lt;p&gt;@Random / Pavel&lt;/p&gt;
&lt;p&gt;I think I understand your points better now. &amp;nbsp;For structs, as they are value types you&amp;#39;d expect Equals() to work when two have the same content, therefore the GetHashCode should be the same between two with equal content. &amp;nbsp;Likewise for strings, &amp;quot;a&amp;quot; and &amp;quot;a&amp;quot; should be equal (even though the object ref may not be) - Tuple, String, Uri and XName, I see. &amp;nbsp;I think then you could say that you ought to implement GetHashCode when you want the Equals() operator to be a logical Equals and not a ReferenceEquals? &amp;nbsp;is that a fair characterization?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136626" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10136450</link><pubDate>Thu, 03 Mar 2011 14:35:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136450</guid><dc:creator>Random832</dc:creator><description>&lt;p&gt;&amp;quot;so for structs it is a matter of the ValueType.GetHashCode() being inefficient - ok - why isnt this fixed in the CLR?&amp;quot;&lt;/p&gt;
&lt;p&gt;What makes you think a fully general implementation of this could be more efficient than it is? The reason you&amp;#39;re supposed to override it is to provide an implementation that&amp;#39;s _not_ fully general and doing lots of extra checking that your type doesn&amp;#39;t need [e.g. iterating over the fields with reflection to see if any of them override GetHashCode]&lt;/p&gt;
&lt;p&gt;&amp;quot;But what is the advantage of what you propose for classes that &amp;#39;is an &amp;quot;reference value type&amp;quot; (i.e. the interesting part about it is solely the data that it represents, not its object identity; this should generally also imply immutability).&amp;#39;? &amp;nbsp;What does that add?&amp;quot;&lt;/p&gt;
&lt;p&gt;Well, the most common example of a &amp;quot;reference value type&amp;quot; is String. How would you feel if you were unable to reliably use a String as a key in a hash table?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136450" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10136120</link><pubDate>Wed, 02 Mar 2011 19:17:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136120</guid><dc:creator>Alex Lo</dc:creator><description>&lt;p&gt;@Pavel, &lt;/p&gt;
&lt;p&gt;so for structs it is a matter of the ValueType.GetHashCode() being inefficient - ok - why isnt this fixed in the CLR?&lt;/p&gt;
&lt;p&gt;But what is the advantage of what you propose for classes that &amp;#39;is an &amp;quot;reference value type&amp;quot; (i.e. the interesting part about it is solely the data that it represents, not its object identity; this should generally also imply immutability).&amp;#39;? &amp;nbsp;What does that add?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136120" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10135984</link><pubDate>Wed, 02 Mar 2011 14:01:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10135984</guid><dc:creator>Paul G</dc:creator><description>&lt;p&gt;Good article, thanks. A good part two would expand on some of the comments with strategies for creating hash values.&lt;/p&gt;
&lt;p&gt;In the past I&amp;#39;ve been stuck in the situation of not fully understanding how the hash value was used internally (only that equal objects should return equal hashes). Therefore when implementing for objects with mixtures of strings and values I&amp;#39;ve often found myself concatenating the values into a string (eg name + &amp;quot;,&amp;quot; + age) and then returning .GetHashCode() of the string. &lt;/p&gt;
&lt;p&gt;It seems too easy. Is there a downside to this approach?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10135984" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10135895</link><pubDate>Wed, 02 Mar 2011 09:18:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10135895</guid><dc:creator>Bill P. Godfrey</dc:creator><description>&lt;p&gt;Correction. I was thinking of the Thread ID, not the Process ID.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10135895" width="1" height="1"&gt;</description></item><item><title>re: Guidelines and rules for GetHashCode</title><link>http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx#10135814</link><pubDate>Wed, 02 Mar 2011 04:10:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10135814</guid><dc:creator>Simon Buchan</dc:creator><description>&lt;p&gt;@BinaryCode: Wow, that was fast, thanks!&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10135814" width="1" height="1"&gt;</description></item></channel></rss>