某些.NET方法使用StringComparison作为参数,有些使用StringComparer(通常采用IComparer的形式)。差异很明显。是否有一些优雅的方法如何从 StringComparer 获得 StringComparison ,反之亦然?
我总是可以编写使用Case
语句的简单方法,但也许.NET中已经出现了一些我忽略的东西。
答案 0 :(得分:6)
没有开箱即用的东西,但您可以在比较和比较器之间创建一个简单的映射:
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 }
}
当你需要适当的比较器时:
var invariantComparer = comparsionToComparer[StringComparsion.InvariantCulture];
修改强>
使用C#-6 Dictionary Initializer语法:
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
};
另外,Jons answer指的是线程current-culture的问题,我放弃了它,应该考虑到它
答案 1 :(得分:6)
从StringComparison
转到StringComparer
很简单 - 只需创建一个Dictionary<StringComparison, StringComparer>
:
var map = new Dictionary<StringComparison, StringComparer>
{
{ StringComparison.Ordinal, StringComparer.Ordinal },
// etc
};
每个StringComparer
值都有一个StringComparison
,因此这种方式很容易实现。请注意,StringComparer.CurrentCulture
取决于当前的线程文化 - 因此,如果您填充字典然后修改线程的文化(或者从具有不同文化的不同线程中执行),您可能会最终得到错误的价值。您可能需要Dictionary<StringComparison, Func<StringComparer>>
:
var map = new Dictionary<StringComparison, Func<StringComparer>>
{
{ StringComparison.Ordinal, () => StringComparer.Ordinal },
// etc
};
然后,您可以随时通过调用委托来获得比较器:
var comparer = map[comparison]();
走另一条路是不可行的,因为不是每个StringComparer
都一个合适的StringComparison
。例如,假设我(在英国)为法语(StringComparer
创建StringComparer.Create(new CultureInfo(..., true))
。StringComparison
代表什么?它对于当前文化不正确,不变量文化或序数比较。
答案 2 :(得分:1)
vb.net版本基于已接受的答案(和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}
}
用法:
Dim comparer As StringComparer = map(comparison)()
答案 3 :(得分:0)
任何需要快速复制+粘贴的人的完整扩展方法:
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();
}
}
答案 4 :(得分:0)
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");
}