2015-09-24 9 views

risposta

6

Andando StringComparison-StringComparer è semplice - basta creare un Dictionary<StringComparison, StringComparer>:

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

C'è un valore StringComparer per ogni valore di StringComparison, quindi funziona in modo molto semplice. Intendiamoci, StringComparer.CurrentCulture dipende dalla cultura del thread corrente, quindi se si popola il dizionario e quindi si modifica la cultura del thread (o lo si fa da un thread diverso con una cultura diversa) si può finire con il valore sbagliato. È potenzialmente desidera un Dictionary<StringComparison, Func<StringComparer>>:

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

Poi si può ottenere un operatore di confronto in qualsiasi momento richiamando il delegato:

var comparer = map[comparison](); 

in senso contrario è irrealizzabile, perché non tutti i StringComparerha un adeguato StringComparison. Per esempio, supponiamo che (nel Regno Unito) creare un StringComparer per il francese (StringComparer.Create(new CultureInfo(..., true)). Il che StringComparison fa che rappresentano? Non è corretto per la cultura corrente, le impostazioni cultura invarianti, o confronti ordinali.

+0

Grazie per aver dimostrato che "la mappatura dinamica" è utile laddove è probabile che la cultura cambi. Forse capisco anche perché la cosa non sia così semplice che .NET possa offrirlo fuori dagli schemi. – miroxlav

6

Non c'è qualcosa fuori dalla scatola, ma è possibile creare un semplice mappatura te tra il comparsion e l'operatore di confronto:

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 } 
} 

E quando mai è necessario il corretto di confronto:

var invariantComparer = comparsionToComparer[StringComparsion.InvariantCulture]; 

Edit:

Con C# sintassi -6 Dizionario 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 
}; 

Inoltre, Jons answer si riferisce alla questione del thread corrente-cultura, che ho scartato e dovrebbe probabilmente essere prese in considerazione

+0

Sì, questo è fondamentalmente quello che stavo per fare.Prima di scrivere sul codice, stavo chiedendo se .NET avesse qualcosa di simile già dentro. – miroxlav

+0

@miroxlav Non esiste una mappatura esistente che io conosca. –

+0

Sulla base della risposta di Jon, penso che forse capisco perché non c'è qualcosa di simile. Potrebbe non essere così semplice come sembra a prima vista. – miroxlav

1

versione basata sulla risposta accettata (e 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} 
    } 

Usage:

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

An una completa metodo di estensione per chiunque abbia bisogno di copia e incolla veloce:

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(); 
    } 
} 
Problemi correlati