Elegant way to convert between StringComparison and StringComparer?

Some .NET methods use StringComparison as a parameter, some use StringComparer (often in the form of IComparer ). The difference is obvious. Is there an elegant way how to get StringComparison from StringComparer or vice versa?

I can always write a simple method that uses the Case statement, but maybe there is already something in .NET that I'm missing.

+6
source share
5 answers

Moving from StringComparison to StringComparer is simple - just create a Dictionary<StringComparison, StringComparer> :

 var map = new Dictionary<StringComparison, StringComparer> { { StringComparison.Ordinal, StringComparer.Ordinal }, // etc }; 

For each StringComparison value, a StringComparison exists, so this method works very easily. Keep in mind that StringComparer.CurrentCulture depends on the current culture of the streams, so if you fill out the dictionary and then change the culture of the stream (or do it from another stream with a different culture), you may get the wrong value. You potentially want Dictionary<StringComparison, Func<StringComparer>> :

 var map = new Dictionary<StringComparison, Func<StringComparer>> { { StringComparison.Ordinal, () => StringComparer.Ordinal }, // etc }; 

You can then get the mapping at any time by calling the delegate:

 var comparer = map[comparison](); 

Moving the other way is unattainable, since not every StringComparer has a suitable StringComparison . For example, suppose I (in the UK) create a StringComparer for the French language ( StringComparer.Create(new CultureInfo(..., true)) What StringComparison does this mean? This is not true for the current culture, invariant culture, or ordinal comparisons.

+6
source

There is nothing out of the box, but you can create a simple mapping between companion and comparator:

 Dictionary<StringComparison, StringComparer> comparsionToComparer = new Dictionary<StringComparison, System.StringComparer> { { StringComparison.CurrentCulture, StringComparer.CurrentCulture }, { StringComparison.CurrentCultureIgnoreCase, StringComparer.CurrentCultureIgnoreCase }, { StringComparison.InvariantCulture, StringComparer.InvariantCulture }, { StringComparison.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase }, { StringComparison.Ordinal, StringComparer.Ordinal }, { StringComparison.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase } } 

And when you need the right comparator:

 var invariantComparer = comparsionToComparer[StringComparsion.InvariantCulture]; 

Edit:

With C # -6 dictionary initializer syntax:

 Dictionary<StringComparison, StringComparer> comparsionToComparer = new Dictionary<StringComparison, System.StringComparer> { [StringComparison.CurrentCulture] = StringComparer.CurrentCulture, [StringComparison.CurrentCultureIgnoreCase] = StringComparer.CurrentCultureIgnoreCase, [StringComparison.InvariantCulture] = StringComparer.InvariantCulture, [StringComparison.InvariantCultureIgnoreCase] = StringComparer.InvariantCultureIgnoreCase, [StringComparison.Ordinal] = StringComparer.Ordinal, [StringComparison.OrdinalIgnoreCase] = StringComparer.OrdinalIgnoreCase }; 

In addition, the Jons answer refers to the current culture issue that I have discarded and should probably be considered

+6
source

based on the accepted answer (and Option Infer Off ):

 Dim map As New Dictionary(Of StringComparison, Func(Of StringComparer))() _ From { {StringComparison.CurrentCulture, Function() StringComparer.CurrentCulture}, {StringComparison.CurrentCultureIgnoreCase, Function() StringComparer.CurrentCultureIgnoreCase}, {StringComparison.InvariantCulture, Function() StringComparer.InvariantCulture}, {StringComparison.InvariantCultureIgnoreCase, Function() StringComparer.InvariantCultureIgnoreCase}, {StringComparison.Ordinal, Function() StringComparer.Ordinal}, {StringComparison.OrdinalIgnoreCase, Function() StringComparer.OrdinalIgnoreCase} } 

Using:

 Dim comparer As StringComparer = map(comparison)() 
+1
source

The full extension method for anyone who needs a quick copy + paste:

 public static class StringComparisonExtensions { // from http://stackoverflow.com/a/32764112/548304 private static readonly Dictionary<StringComparison, Func<StringComparer>> ComparsionToComparer = new Dictionary<StringComparison, Func<StringComparer>> { [StringComparison.CurrentCulture] = () => StringComparer.CurrentCulture, [StringComparison.CurrentCultureIgnoreCase] = () => StringComparer.CurrentCultureIgnoreCase, [StringComparison.InvariantCulture] = () => StringComparer.InvariantCulture, [StringComparison.InvariantCultureIgnoreCase] = () => StringComparer.InvariantCultureIgnoreCase, [StringComparison.Ordinal] = () => StringComparer.Ordinal, [StringComparison.OrdinalIgnoreCase] = () => StringComparer.OrdinalIgnoreCase }; /// <summary> /// Retrieves a string comparer for the given StringComparison. /// </summary> public static StringComparer ToComparer(this StringComparison comparison) { return ComparsionToComparer.GetValueOrDefault(comparison)?.Invoke(); } } 
0
source
  public static StringComparer ToComparer(this StringComparison comparison) { switch (comparison) { case StringComparison.CurrentCulture: return StringComparer.CurrentCulture; case StringComparison.CurrentCultureIgnoreCase: return StringComparer.CurrentCultureIgnoreCase; case StringComparison.InvariantCulture: return StringComparer.InvariantCulture; case StringComparison.InvariantCultureIgnoreCase: return StringComparer.InvariantCultureIgnoreCase; case StringComparison.Ordinal: return StringComparer.Ordinal; case StringComparison.OrdinalIgnoreCase: return StringComparer.OrdinalIgnoreCase; default: break; } throw new NotImplementedException("Unknown StringComparison"); } 
0
source

Source: https://habr.com/ru/post/1232198/


All Articles