Metodo per aggiungere nuovi o aggiornare elementi esistenti nel dizionario


235

In alcuni codici legacy ho visto il seguente metodo di estensione per facilitare l'aggiunta di un nuovo elemento valore-chiave o l'aggiornamento del valore, se la chiave esiste già.

Metodo-1 (codice legacy).

public static void CreateNewOrUpdateExisting<TKey, TValue>(
    this IDictionary<TKey, TValue> map, TKey key, TValue value)
{            
    if (map.ContainsKey(key))
    {
        map[key] = value;
    }
    else
    {
        map.Add(key, value);
    }
}

Tuttavia, ho verificato che map[key]=value fa esattamente lo stesso lavoro. Cioè, questo metodo potrebbe essere sostituito con il Metodo 2 di seguito.

Metodo-2.

public static void CreateNewOrUpdateExisting<TKey, TValue>(
    this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
    map[key] = value;
}

Ora, la mia domanda è ... Potrebbe esserci qualche problema se sostituisco Method-1 con Method-2? Si romperà in ogni possibile scenario?

Inoltre, penso che questa sia stata la differenza tra HashTable e Dictionary. HashTable consente di aggiornare un elemento o aggiungere un nuovo elemento utilizzando l'indicizzatore mentre Dizionario no !! Questa differenza è stata eliminata nelle versioni C #> 3.0?

L'obiettivo di questo metodo non è un'eccezione se l'utente invia nuovamente lo stesso valore-chiave, il metodo dovrebbe semplicemente aggiornare la voce con il nuovo valore e creare una nuova voce se al metodo è stata inviata una nuova coppia chiave-valore .

Risposte:


243

Potrebbero esserci problemi se sostituisco il Metodo 1 con il Metodo 2?

No, basta usare map[key] = value. Le due opzioni sono equivalenti.


Per quanto riguarda Dictionary<>vs. Hashtable: Quando si avvia Reflector, si vede che il setter indicizzatore di entrambe le classi chiamano this.Insert(key, value, add: false);ed il addparametro è responsabile per un'eccezione, quando si inserisce una chiave duplicata. Quindi il comportamento è lo stesso per entrambe le classi.


44

Non c'è problema. Vorrei anche rimuovere il CreateNewOrUpdateExistingdalla fonte e utilizzarlo map[key] = valuedirettamente nel tuo codice, perché questo è molto più leggibile, perché gli sviluppatori saprebbero di solito cosa map[key] = valuesignifica.


22

Vecchia domanda, ma sento che dovrei aggiungere quanto segue, ancora di più perché .net 4.0 era già stato lanciato al momento della stesura della domanda.

A partire da .net 4.0 c'è lo spazio dei nomi System.Collections.Concurrent che include raccolte che sono thread-safe.

La collezione System.Collections.Concurrent.ConcurrentDictionary<>fa esattamente quello che vuoi. Ha ilAddOrUpdate() metodo con l'ulteriore vantaggio di essere thread-safe.

Se ti trovi in ​​uno scenario ad alte prestazioni e non stai gestendo più thread delle risposte già fornite di map[key] = value sono più veloci.

Nella maggior parte degli scenari questo vantaggio in termini di prestazioni è insignificante. In tal caso, consiglierei di utilizzare ConcurrentDictionary perché:

  1. È nel framework: è più testato e non sei tu quello che deve mantenere il codice
  2. È scalabile: se passi al multithreading il tuo codice è già pronto per questo

7

Funzionalmente, sono equivalenti.

Performance-wise map[key] = value sarebbe più veloce, poiché stai solo effettuando una singola ricerca anziché due.

Per quanto riguarda lo stile, più corto è, meglio è :)

Il codice nella maggior parte dei casi sembrerà funzionare bene in un contesto multi-thread. Tuttavia, non è thread-safe senza ulteriore sincronizzazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.