“Подробный Словарь” в C#, 'переопределяют новый' это [] или реализуют IDictionary

Все, что я хочу, является словарем, который говорит мне, какой ключ он не мог найти вместо просто высказывания The given key was not present in the dictionary.

Я кратко рассмотрел выполнение подкласса с override new this[TKey key], но чувствовавший это было немного hacky, таким образом, я пошел с реализацией интерфейса IDictionary и передачей всего через непосредственно к внутреннему Словарю, при этом единственная дополнительная логика была в индексаторе:

public TValue this[TKey key]
{
    get
    {
        ThrowIfKeyNotFound(key);
        return _dic[key];
    }
    set
    {
        ThrowIfKeyNotFound(key);
        _dic[key] = value;
    }
}
private void ThrowIfKeyNotFound(TKey key)
{
    if(!_dic.ContainsKey(key))
        throw new ArgumentOutOfRangeException("Can't find key [" + key + "] in dictionary");
}

Действительно ли это - правильный/единственный способ пойти? Был бы newing по этому [] действительно быть этим плохо?

8
задан Benjol 27 April 2010 в 05:33
поделиться

3 ответа

Похоже, что подходит для метода расширения:

public static class SomeUtilClass {
    public static TValue VerboseGetValue<TKey, TValue>(
        this IDictionary<TKey, TValue> data, TKey key)
    {
        TValue result;
        if (!data.TryGetValue(key, out result)) {
            throw new KeyNotFoundException(
                "Key not found: " + Convert.ToString(key));
        }
        return result;
    }
}

Затем он будет работать со всеми вашими существующими словарями всякий раз, когда вы вызываете VerboseGetValue , например:

    var data = new Dictionary<int, string> { { 123, "abc" } };
    Console.WriteLine(data.VerboseGetValue(123));
    Console.WriteLine(data.VerboseGetValue(456));
10
ответ дан 5 December 2019 в 12:09
поделиться

Почему бы не выполнять ContainsKey и проверять наличие ключа перед тем, как касаться базового словаря,

get {
    try {
        return _dic[key];
    }
    catch (ArgumentOutOfRangeException) {
        throw new ArgumentOutOfRangeException(......);
    }
}

Таким образом, вы платите только за дополнительная проверка в случае сбоя - случай успеха, который, надеюсь, встречается чаще, не требует дополнительного поиска по словарю. Это хорошо для get, но установить сложнее, поскольку поведение set по умолчанию всегда работает. Если вы этого не хотите, вам нужно сначала проверить наличие ключа.

3
ответ дан 5 December 2019 в 12:09
поделиться

Если вы хотите сделать это, вам придется так или иначе бросить свой собственный. Но я собираюсь спросить, ПОЧЕМУ вы хотели бы это сделать?

1
ответ дан 5 December 2019 в 12:09
поделиться
Другие вопросы по тегам:

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