简体   繁体   中英

C# string case insensitive class for file paths

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 .

  • Advantage: No need to implement a new class, just use the existing framework.
  • Big Disadvantage: Very easy to forget these while developing new code. (We have many strings in the application that are not case insensitive)

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);
    }
}
  • Advantage: Very optimize, use the existing string methods, and easy to use.
  • Disadvantage: Need to maintain the IgnoreCaseString class.

Option 3:

Use Uri class which is designated for it.

  • Advantage: Existing class, easy to use.
  • Disadvantage: Memory and performance overhead.

The question:

  • Is there any built-in or easy way to do it?
  • Is there another option that I miss?

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 use StringComparer.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 overrides Equals , GetHashCode and operator == with StringComparison.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM