The scenario:
We have on our.Net Core 3.1 application many file paths (of windows OS) that we need to compare and store in Hashsets and Dictionaries that use string comparison (case insensitive).
I tried to find an easy way to handle all these file paths strings and I found 3 options:
Option 1:
Use StringComparison.OrdinalIgnoreCase
and use StringComparer.OrdinalIgnoreCase
.
Option 2:
Create a IgnoreCaseString
class that wraps the string
class and overrides Equals
, GetHashCode
and operator ==
with StringComparison.OrdinalIgnoreCase
.
public sealed class IgnoreCaseString
{
public IgnoreCaseString(string originalString)
{
this.OriginalString = originalString;
}
public string OriginalString { get; }
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
return true;
if (!(obj is IgnoreCaseString filePathString))
return false;
return OriginalString.Equals(filePathString.OriginalString, StringComparison.OrdinalIgnoreCase);
}
public static bool operator ==(IgnoreCaseString a, IgnoreCaseString b)
{
return Equals(a, b);
}
public static bool operator !=(IgnoreCaseString a, IgnoreCaseString b)
{
return !Equals(a, b);
}
public override int GetHashCode()
{
return OriginalString.GetHashCode(StringComparison.OrdinalIgnoreCase);
}
}
IgnoreCaseString
class.Option 3:
Use Uri
class which is designated for it.
The question:
file paths that we need to compare and store
That already screams case sensitivity. Only Windows has case insensitive paths, all other modern operating systems (for the better or worse) are case sensitive. You should play it safe and stick to case sensitivity.
In fact I'd challenge you to think of how you would get a path of the wrong casing on any OS -- manual entry from a spreadsheet or something? In that case I'd add a "Browse" button that opens a standard open file dialog and gives you the correct string.
#1, Use
StringComparison.OrdinalIgnoreCase
and useStringComparer.OrdinalIgnoreCase
.
It's an okay solution if you ignore the first part. Anything about "forgetting" things can usually be done with custom code analysis modules, and it's fast and memory efficient by itself.
#2, Create a
IgnoreCaseString
class that wraps the string class and overridesEquals
,GetHashCode
andoperator ==
withStringComparison.OrdinalIgnoreCase
.
Perhaps a better name would be CaseInsensitiveString
, as Ignore implies an active action being performed, while your string doesn't perform any actions, it just passively behaves differently.
This solution uses more memory than the previous one, and it doesn't let you use modern constructs like Span
for less memory overhead in tight string processing scenarios.
Your implementation is also broken, re-read your operators:
public static bool operator ==(IgnoreCaseString a, IgnoreCaseString b)
{
return string.Equals(a, b);
}
#3, Use
Uri
class which is designated for it.
It's meant for URI protocol paths, of which file://
is one of. It's not meant for local disk paths, though of course it can encode them with the file://
handler. I agree with you, seems overkill.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.