Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy might a System.String object not cache its hash code?
    text
    copied!<p>A glance at the source code for <a href="http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx" rel="noreferrer"><code>string.GetHashCode</code></a> using <a href="http://www.red-gate.com/products/reflector/" rel="noreferrer">Reflector</a> reveals the following (for mscorlib.dll version 4.0):</p> <pre><code>public override unsafe int GetHashCode() { fixed (char* str = ((char*) this)) { char* chPtr = str; int num = 0x15051505; int num2 = num; int* numPtr = (int*) chPtr; for (int i = this.Length; i &gt; 0; i -= 4) { num = (((num &lt;&lt; 5) + num) + (num &gt;&gt; 0x1b)) ^ numPtr[0]; if (i &lt;= 2) { break; } num2 = (((num2 &lt;&lt; 5) + num2) + (num2 &gt;&gt; 0x1b)) ^ numPtr[1]; numPtr += 2; } return (num + (num2 * 0x5d588b65)); } } </code></pre> <p>Now, I realize that <a href="http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx#remarksToggle" rel="noreferrer">the implementation of <code>GetHashCode</code> is not specified and is implementation-dependent</a>, so the question "is <code>GetHashCode</code> implemented in the form of X or Y?" is not really answerable. I'm just curious about a few things:</p> <ol> <li>If Reflector has disassembled the DLL correctly and this <em>is</em> the implementation of <code>GetHashCode</code> (in my environment), am I correct in interpreting this code to indicate that a <code>string</code> object, based on this particular implementation, would not cache its hash code?</li> <li>Assuming the answer is yes, why would this be? It seems to me that the memory cost would be minimal (one more 32-bit integer, a drop in the pond compared to the size of the string itself) whereas the savings would be significant, especially in cases where, e.g., strings are used as keys in a hashtable-based collection like a <code>Dictionary&lt;string, [...]&gt;</code>. And since the <code>string</code> class is immutable, it isn't like the value returned by <code>GetHashCode</code> will ever even change.</li> </ol> <p>What could I be missing?</p> <hr> <p><strong>UPDATE</strong>: In response to Andras Zoltan's closing remark:</p> <blockquote> <p>There's also the point made in Tim's answer(+1 there). If he's right, and I think he is, then there's no guarantee that a string is actually immutable after construction, therefore to cache the result would be wrong.</p> </blockquote> <p>Whoa, <em>whoa</em> there! This is an interesting point to make (and <a href="http://philosopherdeveloper.wordpress.com/2010/05/28/are-strings-really-immutable-in-net/" rel="noreferrer">yes it's very true</a>), but I <strong>really doubt</strong> that this was taken into consideration in the implementation of <code>GetHashCode</code>. The statement "therefore to cache the result would be wrong" implies to me that the framework's attitude regarding strings is "Well, they're <em>supposed to be</em> immutable, but really if developers want to get sneaky they're mutable so we'll treat them as such." <strong>This is definitely not how the framework views strings</strong>. It fully relies on their immutability in so many ways (interning of string literals, assignment of all zero-length strings to <code>string.Empty</code>, etc.) that, basically, if you mutate a string, you're writing code whose behavior is entirely undefined and unpredictable.</p> <p>I guess my point is that for the author(s) of this implementation to worry, "What if this string instance is modified between calls, even though the class as it is publicly exposed is immutable?" would be like for someone planning a casual outdoor BBQ to think to him-/herself, "What if someone brings an atomic bomb to the party?" Look, if someone brings an atom bomb, party's over.</p>
 

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