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