if I want to Add a new object, it first calculate a hashcode of the key and then compares it against already exiting.
No. It does not have to compare with existing keys. If it had to look at keys, insertion could not be O(1), because time would increase as the number of keys increased (not O(N), because it could use more efficient search algorithms, but also not O(1)).
Instead, the hash value also determines the specific storage location within the dictionary, so the dictionary can set the element value directly in the correct location without checking other hashes at all*, and so maintain O(1) insertion. If there is already an existing element stored at this location, depending on your platform/implementation it will either overwrite or throw an exception (C# will throw an ArgumentException)
What I can't get is how can it be O(1) if to calculate it we still need to iterate through all the characters?
Talking about hashcode calculation. From the Dictionary's perspective, this is irrelevant. The dictionary only sees and references the hash. It's not it's job to account for the time to produce the hash, which, depending on the type, may also be O(1) or may be something much worse. Strings do need to check characters, and will be O(n) for hash calculation, but the Dictionary gets to assume the hash.
The Dictionary is only concerned with complexity increase as the number of elements in the dictionary goes up, where an element is a string-as-a-single-unit rather than the individual characters. The complexity of the individual elements is up to their type, and a Dicationary can use anything as a key — not just a string — such that it would be silly to try to talk about Dictionary insertion time if that were part of the conversation, since we'd always have to revert to the worst possible type imaginable.
* Dictionary types are time-efficient, but sometimes space inefficient... but only the for the references rather than the entire objects, and thanks to math not as much as you might expect.
string.GetHashCodeis not O(1).GetHashCodecall which is > O(1) ? (trying to understand, what you don't understand, here, sorry)Stringin a dictionary. That documentation is for the dictionary only. It does not take into account any cost of calculating the HashCode (which it can not know).