Assigning to an existing key
A Dictionary<TKey, TValue> stores one value per key. To change the value of a key that is already there, assign to it through the indexer:
Dictionary<string, int> scores = new Dictionary<string, int>();
scores["Alice"] = 95;
scores["Bob"] = 87;
scores["Alice"] = 99; // update: Alice is now 99
scores["Charlie"] = 72; // the key is new, so this adds an entry
The same syntax does both jobs. If the key exists, its value is replaced. If it doesn't, a new entry is created. C# has no separate put or replace method for this: the indexer assignment is the update. Code ported from Java often uses put(...) or replace(...), and neither exists on a C# dictionary.
Updating based on the old value
A common update uses the current value. Reading and writing through the indexer works like it does for a variable:
scores["Alice"] = scores["Alice"] + 1;
scores["Alice"] += 1; // same thing
scores["Alice"]++; // also the same
All three lines read the existing value, add one and store it back. They only work when the key exists. For a missing key the read part throws KeyNotFoundException. When a key might be missing, as when you count words, handle the first occurrence yourself:
var counts = new Dictionary<string, int>();
foreach (var word in new[] { "a", "b", "a" }) {
counts[word] = counts.GetValueOrDefault(word, 0) + 1;
}
// counts: a = 2, b = 1
GetValueOrDefault(word, 0) returns 0 for a word that hasn't been seen, so the first assignment sets the count to 1.
Updating only when the key exists
Because the indexer adds missing keys, a typo in the key silently creates a new entry instead of updating the old one. If you want an update that must not add anything, check first:
if (scores.ContainsKey("Alice")) {
scores["Alice"] = 99;
}
Also remember that Add(key, value) is not an update. It throws an ArgumentException when the key is already there. To remove an entry entirely, call Remove(key), which returns true when it found the key.
Updating every entry
To change all values, loop over a copy of the keys and assign through the indexer. The copy keeps the loop safe even if you later decide to add or remove entries:
var scores = new Dictionary<string, int> { ["Alice"] = 95, ["Bob"] = 87 };
foreach (string name in scores.Keys.ToList()) {
scores[name] += 5;
}
// Alice is 100, Bob is 92
TryAdd and values that are collections
TryAdd(key, value) adds an entry only when the key is missing and returns false otherwise, with no exception. It is the opposite of an overwrite: the old value stays.
If the value is itself a list, you don't need to assign to the key to change it. Fetch the list and modify it, because the dictionary stores a reference to the same list:
var groups = new Dictionary<string, List<int>>();
groups["even"] = new List<int>();
groups["even"].Add(2);
groups["even"].Add(4);
The exercise, step by step
The lesson starts with a dictionary holding Alice's and Bob's scores, and asks you to set Alice's score to 99.
- Look at the key. Alice's score is stored under the string
"Alice", so that exact string is the key to use. - Assign to it. Write
scores["Alice"] = 99;below the existing lines. The old value, 95, is replaced, and the dictionary still has two entries.
Dictionary<string, int> scores = new Dictionary<string, int>();
scores["Alice"] = 95;
scores["Bob"] = 87;
scores["Alice"] = 99;
Common mistakes
- Using
Addto update. A secondAddwith the same key throws. - Calling
putorreplace. They don't exist in C#. Use the indexer. - Misspelling the key.
scores["alice"] = 99;compiles and runs, but it adds a second entry and leaves"Alice"at 95, because keys are case-sensitive. - Adding keys inside a
foreachover the dictionary. A new key added while you enumerate throws anInvalidOperationException. When a loop needs to add entries, loop over a copy of the keys such asscores.Keys.ToList(), which needsusing System.Linq;. - Declaring the variable again. Writing
Dictionary<string, int> scores = ...a second time would create a new dictionary, or fail to compile in the same scope, rather than update the old one.
Key takeaways
d[key] = valuereplaces the value for an existing key and adds the key when it is new.- Updates that read the old value, such as
d[key]++, need the key to exist. Addthrows for an existing key; use the indexer to update.