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 w
I would create an immutable struct that hold a string, converting the string in the constructor to a standard case (e.g. lowercase). Then you could also add the implicit operator to simplify the creation and override the compare operators. I think this is the simplest way to achieve the behaviour, plus you get only a small overhead (the conversion is only in the constructor).
Here's the code:
public struct CaseInsensitiveString
{
private readonly string _s;
public CaseInsensitiveString(string s)
{
_s = s.ToLowerInvariant();
}
public static implicit operator CaseInsensitiveString(string d)
{
return new CaseInsensitiveString(d);
}
public override bool Equals(object obj)
{
return obj is CaseInsensitiveString && this == (CaseInsensitiveString)obj;
}
public override int GetHashCode()
{
return _s.GetHashCode();
}
public static bool operator ==(CaseInsensitiveString x, CaseInsensitiveString y)
{
return x._s == y._s;
}
public static bool operator !=(CaseInsensitiveString x, CaseInsensitiveString y)
{
return !(x == y);
}
}
Here is the usage:
CaseInsensitiveString a = "STRING";
CaseInsensitiveString b = "string";
// a == b --> true
This works for collections as well.