C# — Нужна реализация IDictionary, которая позволит пустой ключ

В основном я хочу что-то вроде этого:

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

Там кто-либо встроен в библиотеку базовых классов, которые позволяют это? Предыдущий код выдаст исключение во времени выполнения при добавлении пустого ключа.

Спасибо

13
задан Maximilian Mayerl 16 December 2009 в 19:07
поделиться

4 ответа

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:

  1. Create some special constant value to represent the "empty" / "null" case. Kind of hacky and definitely a path to confusion. This can be a viable approach if the dictionary is completely private to some implementation class and you can write some Encode/Decode utility methods to avoid spreading the knowledge of how you translate keys all over the place.
  2. Create your own implementation of IDictionary that internally delegates to a Dictionary<> instance - except for the case of null. This violates the documented expectations for the IDictionary<> interface which does say that null keys should throw an exception. But you may be able to get away with it if it's the only way to solve your real problem. This only works if you own and create the dictionary instance.
  3. Find a way to solve your problem without storing a "null" key in the dictionary. For example, consider not populating the null key in the dictionary and having some special case logic to deal with it. Keys have to be hashable and comparable to work with the underlying implementation, which is why null is prohibited normally.

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.

11
ответ дан 1 December 2019 в 23:31
поделиться

Как насчет этого?

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
ответ дан 1 December 2019 в 23:31
поделиться

NameValueCollection может принимать нулевой ключ, но не реализует IDictionary. Однако было бы довольно легко извлечь из DictionaryBase и предоставить Add / Remove / Indexers и т.д., которые просто заменяют null чем-то встроенным, например:

class MyDictionary : DictionaryBase {
    private readonly object nullKey = new object();

    void Add(object key, string value) {
       if ( key == null ) { key = nullKey; }
       .. call base methods
    }

}
2
ответ дан 1 December 2019 в 23:31
поделиться

Должен ли ключ буквально быть NULL? Ключ в коллекции работает как индекс. Для меня не имеет большого смысла иметь NULL для индекса в коллекции.

Может быть, создать новый класс


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
ответ дан 1 December 2019 в 23:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: