Elegant way of converting between StringComparison and StringComparer?
There isn't something out of the box, but you can create a simple mapping yourself between the comparsion and the comparer:
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-ever you need the proper comparer:
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
};
Also, Jons answer refers to the issue of the threads current-culture, which i discarded and should probably be taken into account
Going from StringComparison
to StringComparer
is simple - just create a Dictionary<StringComparison, StringComparer>
:
var map = new Dictionary<StringComparison, StringComparer>
{
{ StringComparison.Ordinal, StringComparer.Ordinal },
// etc
};
There is a StringComparer
for every StringComparison
value, so that way works really easily. Mind you, StringComparer.CurrentCulture
depends on the current thread culture - so if you populate the dictionary and then modify the thread's culture (or do it from a different thread with a different culture) you may end up with the wrong value. You potentially want a Dictionary<StringComparison, Func<StringComparer>>
:
var map = new Dictionary<StringComparison, Func<StringComparer>>
{
{ StringComparison.Ordinal, () => StringComparer.Ordinal },
// etc
};
Then you can get a comparer at any time by invoking the delegate:
var comparer = map[comparison]();
Going the other way is infeasible, because not every StringComparer
has a suitable StringComparison
. For example, suppose I (in the UK) create a StringComparer
for French (StringComparer.Create(new CultureInfo(..., true))
. Which StringComparison
does that represent? It's not correct for the current culture, the invariant culture, or ordinal comparisons.