This question is not about managing Windows pathnames; I used that only as a specific example of a case-insensitive string. (And I if I change the example now, a whole bunch of comments will be meaningless.)
This may be similar to Possible to create case insensitive string class?, but there isn't a lot of discussion there. Also, I don't really care about the tight language integration that string
enjoys or the performance optimizations of System.String
.
Let's say I use a lot of Windows pathnames which are (normally) case-insensitive (I'm not actually concerned with the many details of actual paths like \
vs. /
, \\\\
being the same as \
, file://
URLs, ..
, etc.). A simple wrapper might be:
sealed class WindowsPathname : IEquatable<WindowsPathname> /* TODO: more interfaces from System.String */
{
public WindowsPathname(string path)
{
if (path == null) throw new ArgumentNullException(nameof(path));
Value = path;
}
public string Value { get; }
public override int GetHashCode()
{
return Value.ToUpperInvariant().GetHashCode();
}
public override string ToString()
{
return Value.ToString();
}
public override bool Equals(object obj)
{
var strObj = obj as string;
if (strObj != null)
return Equals(new WindowsPathname(strObj));
var other = obj as WindowsPathname;
if (other != null)
return Equals(other);
return false;
}
public bool Equals(WindowsPathname other)
{
// A LOT more needs to be done to make Windows pathanames equal.
// This is just a specific example of the need for a case-insensitive string
return Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase);
}
}
Yes, all/most of the interfaces on System.String should probably be implemented; but the above seems like enough for discussion purposes.
I can now write:
var p1 = new WindowsPathname(@"c:\foo.txt");
var p2 = new WindowsPathname(@"C:\FOO.TXT");
bool areEqual = p1.Equals(p2); // true
This allows me to "talk about" WindowsPathname
s in my code rather than a implementation detail like StringComparison.OrdinalIgnoreCase
. (Yes, this specific class could also be extended to handle \
vs /
so that c:/foo.txt would be equal to C:\FOO.TXT; but that's not the point of this question.) Furthermore, this class (with additional interfaces) will be case-insensitive when instances are added to collections; it would not necessary to specify an IEqualityComparer
. Finally, a specific class like this also makes it easier to prevent "non-sense" operations such as comparing a file system path to a registry key.
The question is: will such approach be successful? Are there any serious and/or subtle flaws or other "gotchas"? (Again, having to do with trying to setup a case-insensitive string class, not managing Windows pathnames.)