C# Dictionary: Add or [key]=value?
Tags: csharp, beginners
Published: 2019-11-22 07:33:06

Recently I came across an interesting problem that threw me off initially. Now let me preface this with the fact that I have been using C# daily for almost three years now so I am by no means an expert like Jon Skeet but I am no beginner. If you want a [TL;DR](#tldr), as always scroll to the bottom.

So the problem was pretty simple, print out a list of the number of occurrences in an array. 

```csharp
var dict = new Dictionary<int, int>();
var nums = new int[]{1,1,2,3,3,3,4};

foreach (var num in nums)
{
	if(dict.TryGetValue(num,out int val)){
		dict[num] += 1;	
	}
	else{
		dict.Add(num,1);
	}
}

foreach (var num in dict)
{
	Console.WriteLine($"Key: {num.Key}, Occurence: {num.Value}");
}
```

This prints out what you would expect:
![](https://thepracticaldev.s3.amazonaws.com/i/i2qw2jok898o94wtikh5.png)

However when I tried to use the `[key]=value` way, I got an error, the ever so common `KeyNotFoundException`.

```csharp
var dict = new Dictionary<int, int>();
var nums = new int[]{1,1,2,3,3,3,4};

foreach (var num in nums)
{
	dict[num] += 1; 
}

foreach (var num in dict)
{
	Console.WriteLine($"Key: {num.Key}, Occurence: {num.Value}");
}

```

That was odd to me because I had always thought that was equivalent to Add *or* update. Of course I could have gone my merry way and taken a mental note to always use the Add method in combination with TryGetValue which would have caught the exception but by golly, I had to know I was not going insane here with such a simple task like adding a value to a dictionary. 

After digging into the reference source, the two look pretty identical.
```csharp
public void Add(TKey key, TValue value)
{
    this.Insert(key, value, true);
}

public TValue this[TKey key]
{
    get
    {
        int index = this.FindEntry(key);
        if (index >= 0)
        {
            return this.entries[index].value;
        }
        ThrowHelper.ThrowKeyNotFoundException();
        return default(TValue);
    }
    set
    {
        this.Insert(key, value, false);
    }
}
```
The only difference was the third argument but after taking a look at Insert, that is really only used to throw an exception if there is a duplicate Key. 

But then it dawned on me that I am [shaving the yak](https://www.hanselman.com/blog/YakShavingDefinedIllGetThatDoneAsSoonAsIShaveThisYak.aspx) and I needed to take a step. Lo and behold, with that step back I realized that it was the operator precedence. The issue wasn't with the dictionary, it was with the `+=` that I was doing. Because of that, the code was doing a get and then setting the value to an increment of plus one. However, the value doesn't exist which is where the KeyNotFound exception was thrown.

Finally, I can push off the imposter syndrome for a little while longer. Thank you for reading and I hope everyone has fun programming!

### TL;DR <a name="tldr"></a> 
First off, if I had checked StackOverflow first, I would have realized many people have thought of this and there's an excellent answer to this [here](https://stackoverflow.com/a/1841639). 

But to summarize, [key]=value is not really Add or Update in my case because of the order of precedence with operators. Due to `dict[num] += 1`, the code is doing a `get` on the `num` value in the dictionary and throws an exception because the value does not exist.