Reputation: 8145
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 into the base class library that allow this? The preceding code will throw an exception at runtime when adding the null key.
Upvotes: 19
Views: 12337
Reputation: 103
If key is enum, you can use not existing value instead of null like (YourEnum)(-1)
Upvotes: 1
Reputation: 2303
No need for a different implementation of Dictionary.
Take a look at my answer here: https://stackoverflow.com/a/22261282/212272
You will also be able to keep your dictionary strongly typed:
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]);
Upvotes: 1
Reputation: 1300
You can simply use ValueTuple as a wrapper for key, for example:
Dictionary<ValueTuple<string?>, string>
Upvotes: 1
Reputation: 439
A slight variation on jestro's answer to make for a cleaner(to me) solution that makes it more explicit what you are trying to do. Obviously this could be extended as needed. But you get the picture, just make a wrapper.
public class NullDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
private TValue _default;
public new TValue this[TKey key]
{
get {
if(key == null)
{
return _default;
}
return _decorated[key];
}
}
private Dictionary<TKey, TValue> _decorated;
public NullDictionary( Dictionary<TKey,TValue> decorate, TValue defaultValue = default)
{
_decorated = decorate;
_default = defaultValue;
}
}
Upvotes: -1
Reputation: 131646
You could avoid using null and create a special singleton value class that does the same thing. 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 fail to work if you intend to make your collection more strongly typed - let's say for example you want the key to be a string. Since string is sealed you can't inherit from it to create a "special value" substitute for null. Your alternatives become a bit more complicated. You could:
As an aside, does your dictionary key really need the key to be object
? This can lead to subtle bugs due to reference equality being used where you may have intended Equals() to be evaluated as the basis for comparison.
Upvotes: 12
Reputation:
Does the key literally need to be NULL? The key in the collection works out to be an index. It doesn't make a lot of sense to me to have NULL for an index in a 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);
Upvotes: 0
Reputation: 2593
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; }
}
}
}
Upvotes: 4
Reputation: 69242
NameValueCollection can take a null key but it does not implement IDictionary. It would however be pretty easy to derive from DictionaryBase and provide Add/Remove/Indexers etc that simply replace null with something built in like:
class MyDictionary : DictionaryBase {
private readonly object nullKey = new object();
void Add(object key, string value) {
if ( key == null ) { key = nullKey; }
.. call base methods
}
}
Upvotes: 1