一些.NET方法使用StringComparison作为参数,一些使用StringComparer(通常以IComparer的形式)。差别很明显。有没有一些优雅的方式如何获得StringComparison从StringComparer或反之亦然?StringComparison和StringComparer之间转换的优雅方式?
我总是可以写简单的方法,它使用Case
语句,但也许已经有一些东西存在于.NET中,我忽略了它。
一些.NET方法使用StringComparison作为参数,一些使用StringComparer(通常以IComparer的形式)。差别很明显。有没有一些优雅的方式如何获得StringComparison从StringComparer或反之亦然?StringComparison和StringComparer之间转换的优雅方式?
我总是可以写简单的方法,它使用Case
语句,但也许已经有一些东西存在于.NET中,我忽略了它。
从StringComparison
去StringComparer
很简单 - 只需创建一个Dictionary<StringComparison, StringComparer>
:
var map = new Dictionary<StringComparison, StringComparer>
{
{ StringComparison.Ordinal, StringComparer.Ordinal },
// etc
};
对于每个StringComparison
值都有一个StringComparer
,所以这种方式非常容易。请注意,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
这是否代表什么?这不是当前的文化,不变的文化,或有序比较正确的。
没有什么现成的,但你可以之比较与比较器之间自己创建一个简单的映射:
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<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指线程当前文化的问题,这是我丢弃,也许应该考虑到
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)()
的一个完整的需要快速复制+粘贴的任何人的扩展方法:
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();
}
}
感谢您表明,“动态映射”在文化可能发生变化的地方非常有用。也许我也明白为什么事情并不那么简单,.NET可以提供开箱即用的功能。 – miroxlav