+10  A: 

Which value would you want it to return if it didn't exist in the map already? It could return default(TValue) - but then it would be somewhat easy to accidentally use a value assuming it was correct. Note that if you want that behaviour, you can use:

get {
  string value;
  if (!_mydic.TryGetValue(key, out value))
    value = default(string);
  return value;
}

I wouldn't personally recommend it in general, but if you're happy not to be able to distinguish (via this indexer) between a key with a null value and a missing key, it will do the trick.

Note that your setter can me a lot simpler - just

_mydic[key] = value;

will overwrite if necessary.

Jon Skeet
Jon, I'm a little confused. The reason why I have all of that logic in the setter is because of the exception that gets thrown. So I can only use the setter code you had specified if the key already exists... right?
Dave
No--the [] setter will add or overwrite as needed.
Michael Haren
@Dave: See http://msdn.microsoft.com/en-us/library/9tee9ht2.aspx. " If the specified key is not found, a get operation throws a KeyNotFoundException, and **a set operation creates a new element with the specified key**."
Jeff Yates
@Dave - The exception will only be thrown if you try to query the Dictionary with a key that doesn't exist. If you use the Indexer set... it will Add if it doesn't exist. See the documentation here for more information http://msdn.microsoft.com/en-us/library/bb302460.aspx
Nick
I think I must be dyslexic. I'll check it out, thanks.
Dave
@Jon Skeet: I know for `Dictionary<T,K>` my edit does the same thing, but it's a generally good idea to treat the `out` parameter of `TryGet*` as uninitialized. This pattern is consistent for any default/unset value as well.
280Z28
@280Z28: WHy? The rule on an `out` parameter is that the method MUST set it for all execution paths.
Jeff Yates
OK guys, sorry. My memory is bad. I used to have issues with map NOT throwing an exception when the key isn't there, so I'd have to test map for existence so I could then throw an exception. Actually Dictionary is different than map, but it's actually better IMO.
Dave
@Jeff Yates: Must set it to what? What's the difference between uninitialized, and initialized to an unknown value? (Like I said, for `Dictionary<T,K>`, it clearly states this value is set to `default(K)`, but if you code like I put above it's clear exactly what you mean: "I wan't to use this default value if the lookup failed")
280Z28
@280Z28: The documentation for `TryGetValue` documents what the value is so it is clearly not an unknown value (and I would shy away from any API that doesn't document its out parameters fully). That said, if you want a difference default, you'd need an `else` block to set it.
Jeff Yates
+3  A: 

I agree handling the exception is kind of annoying, especially for reference types when getting a null usually makes sense. In either case though you can use Dictionary<>.TryGetValue() to get the value in one call.

Frank Schwieterman
Thanks, I hadn't ever used that call before. I'll look into it!
Dave
A: 

I'm confused. It does, here. The docs even say so:

When you set the property value, if the key is in the Dictionary(TKey, TValue), the value associated with that key is replaced by the assigned value. If the key is not in the Dictionary(TKey, TValue), the key and value are added to the dictionary.

and

KeyNotFoundException: The property is retrieved and key does not exist in the collection.

(no mention of it being thrown during assignment).

Ken
yeah I got mixed up, it was the other way around. going to fix my post.
Dave