To answer the question first we need to take a look at the purpose of a dictionary and underlying technology.
Dictionary
is the list of KeyValuePair<Tkey, Tvalue>
where each value is represented by its unique key. Let's say we have a list of your favorite foods. Each value (food name) is represented by its unique key (a position = how much you like this food).
Example code:
Dictionary<int, string> myDietFavorites = new Dictionary<int, string>()
{
{ 1, "Burger"},
{ 2, "Fries"},
{ 3, "Donuts"}
};
Let's say you want to stay healthy, you've changed your mind and you want to replace your favorite "Burger" with salad. Your list is still a list of your favorites, you won't change the nature of the list. Your favorite will remain number one on the list, only it's value will change. This is when you call this:
/*your key stays 1, you only replace the value assigned to this key
you alter existing record in your dictionary*/
myDietFavorites[1] = "Salad";
But don't forget you're the programmer, and from now on you finishes your sentences with ; you refuse to use emojis because they would throw compilation error and all list of favorites is 0 index based.
Your diet changed too! So you alter your list again:
/*you don't want to replace Salad, you want to add this new fancy 0
position to your list. It wasn't there before so you can either define it*/
myDietFavorites[0] = "Pizza";
/*or Add it*/
myDietFavorites.Add(0, "Pizza");
There are two possibilities with defining, you either want to give a new definition for something not existent before or you want to change definition which already exists.
Add method allows you to add a record but only under one condition: key for this definition may not exist in your dictionary.
Now we are going to look under the hood. When you are making a dictionary your compiler make a reservation for the bucket (spaces in memory to store your records). Bucket don't store keys in the way you define them. Each key is hashed before going to the bucket (defined by Microsoft), worth mention that value part stays unchanged.
I'll use the CRC32 hashing algorithm to simplify my example. When you defining:
myDietFavorites[0] = "Pizza";
What is going to the bucket is db2dc565 "Pizza" (simplified).
When you alter the value in with:
myDietFavorites[0] = "Spaghetti";
You hash your 0 which is again db2dc565 then you look up this value in your bucket to find if it's there. If it's there you simply rewrite the value assigned to the key. If it's not there you'll place your value in the bucket.
When you calling Add function on your dictionary like:
myDietFavorite.Add(0, "Chocolate");
You hash your 0 to compare it's value to ones in the bucket. You may place it in the bucket only if it's not there.
It's crucial to know how it works especially if you work with dictionaries of string or char type of key. It's case sensitive because of undergoing hashing. So for example "name" != "Name". Let's use our CRC32 to depict this.
Value for "name" is: e04112b1
Value for "Name" is: 1107fb5b