2013-04-09 12 views
7

Quando si fa qualcosa di simile:C# dizionario TryGetValue con valori int, come evitare il doppio lookup

int value; 
if (dict.TryGetValue(key, out value)) 
{ 
    if (condition) 
    { 
     //value = 0; this copies by value so it doesn't change the existing value 
     dict[key] = 0; 
    } 
} 
else 
{ 
    dict[key] = 0; 
} 

C'è un modo posso evitare di ricerca indice per sostituire il valore esistente? Sto già verificando che la chiave esista usando TryGetValue, quindi sembra uno spreco dover recuperare di nuovo il valore per indice.

Su una nota separata, come nella parte else {} del mio codice, è generalmente considerato una buona pratica utilizzare l'indicizzatore quando si aggiungono nuovi valori o si sostituiscono vecchi valori e si aggiunge per rendere chiaro che si sta aggiungendo e non sostituendo ? O dovrei semplicemente usare l'indicizzatore ogni volta? Il modo in cui ho imparato ad usare il dizionario, faccio sempre una ricerca TryGetValue e nella parte else gestisco i casi in cui non esiste alcuna chiave.

+0

non lo stai cercando due volte. –

+1

@ DanielA.White: l'uso dell'indicizzatore fa una ricerca IIRC; p – leppie

+1

la tua (condizione) dipende dal valore? –

risposta

4

Esiste un modo per evitare la ricerca dell'indice per sostituire il valore esistente?

Non che io sappia - ma l'accesso dizionario dovrebbe essere molto veloce a meno che non si dispone di una classe personalizzata che viene sovrascritta GetHashCode male.

Se non si verifica un problema di prestazioni a causa della doppia ricerca, lascerei perdere.

+0

Grazie, non sta portando a un problema di prestazioni ma dal momento che questo schema si presenta frequentemente per me ho pensato di chiedere una volta e imparare il modo ottimale di farlo. – tmakino

0

Preferisco definire metodi di estensione della convenienza per cose come questa. Per esempio:

public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue) 
    { 
     TValue value; 
     return dictionary.TryGetValue(key, out value) ? value : defaultValue; 
    } 

    public static TValue GetOrSet<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value) 
    { 
     return dictionary[key] = dictionary.GetValueOrDefault(key, value); 
    } 

Non c'è bisogno di preoccuparsi per le prestazioni di hashing dizionario & ricerche - sono principalmente di leggibilità e la manutenibilità. Con i metodi di estensione di cui sopra, questo genere di cose è un one-liner:

int value = dict.GetOrSet(key, 0); 

(Esonero di responsabilità: non eseguire il controllo if (condition) - raramente ho sperimento questi scenari)

0

È possibile provare questo

Object value; 
if (dict.TryGetValue(key, out value)) 
{ 
    if (condition) 
    { 
     //value.data = 0; this copies by value so it doesn't change the existing value 
     value.data = 0; 
    } 
} 
else 
{ 
    value.data = 0; 
} 

L'essenza della storia è, il tipo che si sta recuperando è un tipo generico e viene allocato su heap. cioè quando lo prendi, uscirà come valore. Tuttavia, se si estrae l'oggetto, sarà un riferimento all'oggetto allocato originale ed è possibile modificare il valore di una particolare proprietà dell'oggetto.

Problemi correlati