Какой механизм является лучшим способом расширения Dictionary для работы с отсутствующими ключами и почему?

Есть небольшое неудобство, с которым я сталкиваюсь - у меня есть Dictionary , который содержит значения, которые могут или

Таким образом, нормальным поведением будет использование индексатора, например:

object result = myDictionary["key"];  

Однако, если «ключ» отсутствует в словаре, это вызывает исключение KeyNotFoundException , поэтому вместо этого вы сделаете следующее:

object val;
if (!myDictionary.TryGetValue("key", out val))
{
    val = ifNotFound;
}

Что нормально, за исключением того, что я могу загрузить их подряд - TryGetValue начинает казаться ужасно неуклюжим.

Таким образом, вариант 1 является расширением method:

public static TValue TryGet<TKey, TValue>(
    this Dictionary<TKey, TValue> input, 
    TKey key, 
    TValue ifNotFound = default(TValue))
{
    TValue val;
    if (input.TryGetValue(key, out val))
    {
        return val;
    }

    return ifNotFound;
}

Что позволяет мне сделать:

object result = myDictionary.TryGet("key1") ?? ifNotFound;

int i = anotherDictionary.TryGet("key2", -1);

Что достаточно просто, но дополнительный метод расширения с именем, аналогичным существующим методам экземпляра, потенциально добавляет путаницу и снижает ремонтопригодность. Это также несовместимо с набором индексатора словаря, который будет обрабатывать отсутствующие ключи.

Таким образом, вариант 2 представляет собой новую реализацию IDictionary с неявным приведением из Dictionary , но индексатор, который возвращает default (TValue) вместо создания исключения KeyNotFoundException .

Это позволяет мне сделать:

ForgivingDictionary<string, object> dict = myDictionary;

object val = dict["key"] ?? ifNotFound;

// do stuff to val, then...
dict["key"] = val;

Итак, теперь получаем и устанавливаем значения согласованы, но типы значений более беспорядочные, и ForgivingDictionary включает намного больше кода.

Оба метода кажутся «беспорядочными» - есть ли лучший способ сделать это уже в .Net?

Оба методы идут на компромиссы, которые могут вызвать путаницу, но является ли один более очевидным / ясным, чем другой? И почему?

17
задан Keith 2 June 2011 в 13:13
поделиться