c# - ticino - Accesso senza distinzione tra maiuscole e minuscole per dizionario generico




riparazione pc bellinzona (2)

Ho un'applicazione che utilizza DLL gestite. Una di queste DLL restituisce un dizionario generico:

Dictionary<string, int> MyDictionary;  

Il dizionario contiene chiavi con lettere maiuscole e minuscole.

Da un altro lato sto ottenendo un elenco di potenziali chiavi (stringa), ma non posso garantire il caso. Sto cercando di ottenere il valore nel dizionario usando i tasti. Ma ovviamente ciò che segue non funzionerà poiché ho una mancata corrispondenza del caso:

bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );  

Speravo che TryGetValue avesse un flag maiuscole / minuscole come menzionato nel documento MSDN , ma sembra che questo non sia valido per i dizionari generici.

C'è un modo per ottenere il valore di quel dizionario ignorando il caso chiave? C'è una soluzione migliore rispetto alla creazione di una nuova copia del dizionario con il parametro StringComparer.OrdinalIgnoreCase corretto?


Non è molto elegante ma nel caso in cui non puoi cambiare la creazione del dizionario, e tutto ciò di cui hai bisogno è un trucco sporco, che ne dici di questo:

var item = MyDictionary.Where(x => x.Key.ToLower() == MyIndex.ToLower()).FirstOrDefault();
    if (item != null)
    {
        TheValue = item.Value;
    }

Non c'è modo di specificare un StringComparer nel punto in cui si tenta di ottenere un valore. Se ci pensate, "foo".GetHashCode() e "FOO".GetHashCode() sono completamente diversi, quindi non esiste un modo ragionevole per implementare una hash senza distinzione tra maiuscole e minuscole in una mappa hash sensibile al maiuscolo / minuscolo.

Tuttavia, è possibile, in primo luogo, creare un dizionario insensibile alle maiuscole e minuscole utilizzando: -

var comparer = StringComparer.OrdinalIgnoreCase;
var caseInsensitiveDictionary = new Dictionary<string, int>(comparer);

Oppure creare un nuovo dizionario insensibile alle maiuscole e minuscole con il contenuto di un dizionario sensibile alle maiuscole e minuscole esistente (se si è sicuri che non vi siano conflitti tra maiuscole e minuscole):

var oldDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var newDictionary = new Dictionary<string, int>(oldDictionary, comparer);

Questo dizionario utilizza quindi l'implementazione GetHashCode() su StringComparer.OrdinalIgnoreCase tale che comparer.GetHashCode("foo") e comparer.GetHashcode("FOO") forniscano lo stesso valore.

In alternativa, se ci sono solo pochi elementi nel dizionario e / o hai solo bisogno di cercare una o due volte, puoi trattare il dizionario originale come IEnumerable<KeyValuePair<TKey, TValue>> e semplicemente iterare su di esso: -

var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var value = myDictionary.FirstOrDefault(x => String.Equals(x.Key, myKey, comparer))?.Value;

O se preferisci, senza LINQ: -

var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
int? value;
foreach (var element in myDictionary)
{
  if (String.Equals(element.Key, myKey, comparer))
  {
    value = element.Value;
    break;
  }
}

Ciò consente di risparmiare il costo della creazione di una nuova struttura dati, ma in cambio il costo di una ricerca è O (n) invece di O (1).





dictionary