title: ToUpperInvariant() – is MSDN wrong on its recommendation?
body: <p>In <a href="https://msdn.microsoft.com/en-us/library/dd465121(v=vs.110).aspx" rel="nofollow">Best Practices for Using Strings in the .NET Framework</a>, StringComparison <a href="https://msdn.microsoft.com/en-us/library/system.stringcomparison(v=vs.110).aspx" rel="nofollow"><code>OrdinalIgnoreCase</code></a> is recommended for case-insensitive file paths. (Let's call it Statement A.)</p>
  
  <p>I can agree with that, because I can create two files in the same directory:</p>
  
  <pre><code>é.txt
  é.txt
  </code></pre>
  
  <p>Their filenames are not the same, second one is composed from <code>e</code> and modifier, so it actually has two letters. (You can try yourself using copy-paste.)</p>
  
  <p>If there was Invariant culture comparison (and not ordinal comparison) in effect, NTFS wouldn't allow these files, because in the same article they explain, that in invariant culture <code>a + ̊  = å</code></p>
  
  <p>But in article on <a href="https://msdn.microsoft.com/en-us/library/system.string.toupperinvariant(v=vs.110).aspx" rel="nofollow"><code>String.ToUpperInvariant()</code></a> there is different recommendation: (Statement B.)</p>
  
  <blockquote>
    <p>If you need the lowercase or uppercase version of an operating system identifier, such as a file name, named pipe, or registry key, use the ToLowerInvariant or ToUpperInvariant methods.</p>
  </blockquote>
  
  <p>I need to create file path collection (in fact <code>HashSet</code>) to detect duplicates. So if I will obey statement B when creating the map, I could end with false positives, because abovementioned filenames <code>é.txt</code> and <code>é.txt</code> will be considered as one. Am I  understanding it correctly that statement B found in MSDN is misleading? Or am I missing something?</p>
  
  <p>I'm about to build a library, preferably without known bugs from start, so I simply don't want to neglect this.</p>
  
  <p>Update: </p>
  
  <p>Statement B seems to have one more issue: ToLowerInvariant() cannot be actually used. Reason (I quote Best practices article): <code>DO: Use ToUpperInvariant rather than ToLowerInvariant when normalizing strings for comparison.</code> Actual reason:  <code>There is a small range of characters that do not roundtrip, and going to lowercase will make these characters unavailable.</code> (<a href="http://blogs.msdn.com/b/bclteam/archive/2005/06/01/424012.aspx#comments" rel="nofollow">source</a>)</p>