title: How can I compare (directory) paths in C#?
body: <p>If I have two <code>DirectoryInfo</code> objects, how can I compare them for semantic equality?  For example, the following paths should all be considered equal to <code>C:\temp</code>:</p>
  <ul>
  <li><code>C:\temp</code></li>
  <li><code>C:\temp\</code></li>
  <li><code>C:\temp\.</code></li>
  <li><code>C:\temp\x\..\..\temp\.</code></li>
  </ul>
  <p>The following may or may not be equal to <code>C:\temp</code>:</p>
  <ul>
  <li><code>\temp</code> if the current working directory is on drive <code>C:\</code></li>
  <li><code>temp</code> if the current working directory is <code>C:\</code></li>
  <li><code>C:\temp.</code></li>
  <li><code>C:\temp...\</code></li>
  </ul>
  <p>If it's important to consider the current working directory, I can figure that out myself, so that's not that important.  Trailing dots are stripped in windows, so those paths really should be equal - but they aren't stripped in unix, so under mono I'd expect other results.</p>
  <p>Case sensitivity is optional.  The paths <strong>may or may not exist</strong>, and the user <strong>may or may not have permissions to the path</strong> - I'd prefer a fast robust method that doesn't require any I/O (so no permission checking), but if there's something built-in I'd be happy with anything &quot;good enough&quot; too...</p>
  <p>I realize that without I/O it's not possible to determine whether some intermediate storage layer happens to have mapped the same storage to the same file (and even with I/O, when things get messy enough it's likely impossible).  However, it should be possible to at least positively identify paths that are equivalent, regardless of the underlying filesystem, i.e. paths that necessarily would resolve to the same file (if it exists) on all possible file-systems of a given type.  The reason this is sometimes useful is (A) because I certainly want to check this first, before doing I/O, (B) I/O sometimes triggers problematic side-effects, and (C) various other software components sometimes mangle paths provided, and it's helpful to be able to compare in a way that's insensitive to most common transformations of equivalent paths, and finally (D) to prepare deployments it's useful to do some sanity checks beforehand, but those occur before the to-be-deployed-on system is even accessible.</p>