Dictionary<TKey,TValue>
has two different ways of adding an item.
void Add(TKey key, TValue value)
: Because you are calling Add
the semantic you are saying is "this is not present, make it be present". So an exception is raised on a duplicate insertion, because it doesn't know if you want the old thing or the new thing.
The indexer (TValue this[TKey key]
) supports assignment, which has the semantic of "I want this to be the answer if I call the indexer getter".
dict.Add(1, 1);
var x = dict[1]; // x == 1
dict.Add(1, 2); // throws
dict.Add(1, 1);
var x = dict[1]; // x == 1;
dict[1] = 2;
var y = dict[1]; // x == 1, y == 2.
var dict = new Dictionary<long, int>();
dict[1] = 35;
var x = dict[1]; // x == 35;
ContainsKey
is almost always the wrong thing to call. If you are safely reading the value, call TryGetValue
, and if you just want to use the dictionary to store whether or not something has been done, use HashSet<T>
. (Whose Add
method returns a bool
(true
if Add added something (it didn't exist), false
if Add did no work (the value already existed))).
In your specific case of wanting to add things to a list, the TryGetValue approach is the best. Or, using ConcurrentDictionary:
TryGetValue:
List<string> list;
// Read the dictionary exactly once
if (!dict.TryGetValue(key, out list))
{
list = new List<string>();
// Write at most once.
dict[key] = list;
}
list.Add(value);
ConcurrentDictionary:
ConcurrentDictionary<long, List<string>> dict = new ConcurrentDictionary<long, List<string>>();
...
List<string> list = dict.GetOrAdd(key, () => new List<string>());
list.Add(value);
See also
http://stackoverflow.com/questions/11027369/how-to-correctly-handle-adding-new-item-to-dictionary – Piotshe Jan 22 '17 at 19:17