2015-09-24 11 views

Odpowiedz

6

przechodząc od StringComparison do StringComparer jest prosta - wystarczy utworzyć Dictionary<StringComparison, StringComparer>:

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

Istnieje StringComparer dla każdej wartości StringComparison, więc ta metoda działa naprawdę łatwo. Pamiętaj, StringComparer.CurrentCulture zależy od aktualnej kultury wątku - więc jeśli zapełnisz słownik, a następnie zmienisz kulturę wątku (lub zrobisz to z innego wątku z inną kulturą), możesz otrzymać błędną wartość. Potencjalnie chcą Dictionary<StringComparison, Func<StringComparer>>:

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

Następnie można uzyskać porównywarka w dowolnym czasie przez wywoływanie delegata:

var comparer = map[comparison](); 

Idąc w drugą stronę jest niemożliwe, ponieważ nie każdy StringComparerma odpowiednim StringComparison. Na przykład załóżmy, że (w Wielkiej Brytanii) stworzyć StringComparer na francuski (StringComparer.Create(new CultureInfo(..., true)). Które StringComparison powoduje, że reprezentują? To nie jest poprawny dla bieżącej kultury, kultury niezmienny lub porządkowych porównań.

+0

Dziękuję za pokazanie, że "dynamiczne mapowanie" jest użyteczne tam, gdzie kultura może się zmienić. Być może rozumiem też, dlaczego to nie jest tak proste, że .NET zaoferuje to po wyjęciu z pudełka. – miroxlav

6

Nie jest to coś po wyjęciu z pudełka, ale można tworzyć proste mapowanie się między comparsion i 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 } 
} 

A kiedy w historii trzeba prawidłowego porównywarka:

var invariantComparer = comparsionToComparer[StringComparsion.InvariantCulture]; 

Edit:

z C# składni -6 słownik 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 
}; 

Również Jons answer odnosi się do kwestii gwinty bieżącym-kultury, którą odrzucono, a powinno być prawdopodobnie uwzględniona

+0

Tak, to jest w zasadzie to, co miałem zamiar zrobić.Przed kodowaniem pytałem, czy .NET ma już coś takiego w środku. – miroxlav

+0

@miroxlav Nie istnieje istniejące mapowanie, które znam. –

+0

Bazując na odpowiedzi Jona, myślę, że być może rozumiem, dlaczego czegoś takiego nie ma. Może nie być tak proste, jak się wydaje na pierwszy rzut oka. – miroxlav

1

wersję na podstawie zaakceptowanej odpowiedzi (i 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} 
    } 

Zastosowanie:

Dim comparer As StringComparer = map(comparison)() 
0

kompletny metoda rozszerzenia dla każdego, kto potrzebuje szybkiego kopiowania + wklejania:

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(); 
    } 
} 
Powiązane problemy