C # - you need an IDictionary implementation that will allow you to use a null key

Basically, I want something like this:

Dictionary<object, string> dict = new Dictionary<object, string>(); dict.Add(null, "Nothing"); dict.Add(1, "One"); 

Are there any built-in base class libraries that allow this? The previous code throws a runtime exception when adding a null key.

thank

+13
collections c # idictionary
Dec 16 '09 at 18:50
source share
5 answers

You can avoid using null and create a special Singleton value class that does the same. For example:

 public sealed class Nothing { public static readonly Nothing Value = new Nothing(); private Nothing() {} } Dictionary<object, string> dict = new Dictionary<object, string>(); dict.add(Nothing.Value, "Nothing"); dict.add(1, "One"); 

This approach will not work if you intend to make your collection more strongly typed - say, for example, you want the key to be a string. Since the string is sealed, you cannot inherit it to create a replacement for the "special value" for null. Your alternatives are getting a little harder. You could:

  • Create a special constant value to represent the empty / null case. Kind of khaki and definitely a path to confusion. This can be a viable approach if the dictionary is completely closed for any implementation class, and you can write some methods of the Encode / Decode utility so as not to spread the knowledge of how you translate keys around the place.
  • Create your own implementation of IDictionary that internally delegates an instance of Dictionary <>, except in the case of null. This violates the documented expectations for the IDictionary <> interface, which says that empty keys should throw an exception. But you can get away from it if this is the only way to solve your real problem. This only works if you own and create an instance of the dictionary.
  • Find a way to solve your problem without storing the "zero" key in the dictionary. For example, consider not filling out the null key in the dictionary and have some special case logic to solve this problem. The keys must be hashed and comparable to working with the underlying implementation, so zero is prohibited in normal mode.

As an aside, is your key dictionary really needed for the object key? This can lead to minor errors due to the use of reference equality, when you can assume that Equals () is evaluated as the basis for comparison.

+11
Dec 16 '09 at 18:57
source share

How about this?

 public class NullableDictionnary<T1, T2> : Dictionary<T1, T2> { T2 null_value; public T2 this[T1 key] { get { if (key == null) { return null_value; } return base[key]; } set { if (key == null) { null_value = value; } else { base[key] = value; } } } } 
+5
Dec 16 '09 at 19:08
source share

NameValueCollection can accept a null key, but does not implement an IDictionary. However, it would be fairly easy to get from DictionaryBase and provide Add / Remove / Indexers, etc., which simply replace zero with something built-in, for example:

 class MyDictionary : DictionaryBase { private readonly object nullKey = new object(); void Add(object key, string value) { if ( key == null ) { key = nullKey; } .. call base methods } } 
+2
Dec 16 '09 at 19:00
source share

Should the key literally be NULL? The key in the collection works as an index. It doesn't make much sense to me to have NULL for the index in the collection.

Maybe create a new class

 public class ObjectEntry { public object objRef; public string desc; public ObjectEntry(object objectReference) { objRef = objectReference; if (objRef = null) {desc = "Nothing";} else {desc = objRef.Description;} //or whatever info you can get from a proper objRef value } } newObj = new ObjectEntry(null); dict.add(newObj, newObj.desc); 
0
Dec 16 '09 at 19:10
source share

No other Dicionary implementation is needed.

Take a look at my answer here: stack overflow

You can also strictly specify your dictionary:

 var dict = new Dictionary<NullObject<int?>, string>(); dict[1] = "one int"; dict[null] = "null int"; Assert.AreEqual("one int", dict[1]); Assert.AreEqual("null int", dict[null]); 
0
Mar 07 '14 at 21:50
source share



All Articles