Darnit, they break the Hashtable (err Dictionary) then ask us how we think they should fix it...
Don't mind the title, I'm just being funny. However, throwing exceptions isn't a funny matter, so go comment on Brad's post as to how you think they should fix the Dictionary issues with exceptions. The change from Hashtable to Dictionary
I have the following comments that I'd like to introduce. First off, Nullable<T> is definitely the way to implement null return values for value types. It is just super great. What I don't like about Nullable<T> is that there is no way to easily find out if the underlying type parameter for your ValueCollection is actually of some Nullable<T>. In other words, is works on closed types, not open types, so you have to do a bunch of voodoo (namely GetGenericTypeDefinition), just to check and see if the type parameter for your ValueCollection is Nullable. Likewise, you'd have to do similar work to find out if it was an object. Might make sense to toss an INullable on Nullable so you can quickly check using an is comparison and provide interface based access to HasValue. Am I wrong here? Am I missing a language feature that would make checking against the open generic type easy?
So the new Dictionary now follows the following: a) If reference type return null, If Nullable<T> then return Nullable<T>.default, If a ValueType that isn't Nullable<T> then throw that weird exception.
My only argument for not just moving to the ContainsKey() model would be the extra calls. Also, you still support the default indexed setter which can either Add a value or update it depending. Not having the null return getter just doesn't make sense.
booleanSettings[“NonExistentKey1“] = foo; // This adds the key if it doesn't exist
foo = booleanSettings[”NonExistentKey2”]; // But this throws an exception...
So I'm definitely thinking things have to be done the right way here (using some nullable feature set). And that the work involved in implementing that within the Dictionary is actually not going to be clean and easy because C# doesn't have a language feature for getting type information on open generic types nor comparing types against open generic types (hint, hint, maybe something could be added to help?). Adding the INullable interface would be a total hack and I don't even know why I suggested it. If you are curious about the open type comparision stuff I'm talking about, check the following code required to compare the types Nullable<string> and Nullable<bool>. The purpose of the comparison is to determine if the underlying type is actually any instance of Nullable irregardless of the type parameters used in the closed types.
// The below is extremely ugly.
Console.WriteLine(typeof(Nullable<string>).GetGenericTypeDefinition() == typeof(Nullable<bool>).GetGenericTypeDefinition());
// This is how it would look if you actually wanted to see if the underlying type parameter used to create
// your ValueCollection/Dictionary. Note this must be used in the dictionary class
(this.GetType().GetGenericArguments.GetGenericTypeDefinition() == typeof(Nullable<int>).GetGenericTypeDefinition());
I sure hope I'm missing a language feature, because that stuff is UGLY.