.net словарь со значением по умолчанию - PullRequest
2 голосов
/ 02 ноября 2010

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

var dict = new DictWithDefValues("not specified");
dict.Add("bob78", "Smart");
dict.Add("jane17", "Doe");
Assert.AreEqual(dict["xxx"], "not specified");

Расширение System.Collections.Generics.Dictionary и переопределение TryGetValue не работает, потому что TryGetValueне виртуальный

Переопределение словаря с нуля (из IDictionary <,>) - это слишком много усилий.

Метод расширения не позволит мне «инициализировать» словарь значением по умолчанию.Я хочу, чтобы потребитель словаря думал, что ключ есть, а не просто dict.GetOrDefault(key, "not specified");

Ответы [ 6 ]

7 голосов
/ 02 ноября 2010

Переопределение словаря с нуля (из IDictionary <,>) - это слишком много усилий

Это действительно лучший вариант.Просто инкапсулируйте Dictionary<,> как члена вашего класса и передайте всех членов в код Словаря.Вам нужно обрабатывать только те свойства и методы, которые вы хотите, чтобы в этом случае отличались.

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

3 голосов
/ 02 ноября 2010

Я думаю, что Рид прав, что Словарь переопределения довольно прост, и если это то, что вам нужно, то это прекрасно.

но все равно кажется излишним создание нового класса для замены

        dict.TryGetValue("xxx", out value);
        value = value ?? "not specified";

с

      value  = dict.GetOrDefault(key, "not specified")
1 голос
/ 21 октября 2016

Этот метод расширения помогает мне;

    public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> source, TKey key, TValue defaultValue = default(TValue))
    {
        TValue found;
        if (source.TryGetValue(key, out found))
        {
            return found;
        }
        else
        {
            return defaultValue;
        }
    }

Он называется так;

dict.GetValueOrDefault("foo", 0) // returns the key under "foo", or 0 if missing.
0 голосов
/ 25 октября 2013

Я заметил, что ваш пример - это словарь строк.Это также строки в моем собственном сценарии, где я хочу подобное поведение.

Возможно, старый добрый класс StringDictionary сделает то, что вы хотите.В отличие от Dictionary<string,string> его метод get_Item возвращает null для ключей, которых нет в словаре.

0 голосов
/ 24 апреля 2013

Попробуйте это

public class DefaultDictionary<Tkey,Tvalue>
    where Tkey: IEquatable<Tkey>
{
    private readonly Func<Tvalue> _getDefault;
    private Dictionary<Tkey, Tvalue> _dict;

    public DefaultDictionary(Func<Tvalue> getDefault = null)
    {
        if (getDefault == null)
        {
            _getDefault = () => default(Tvalue);
        }
        else
        {
            _getDefault = getDefault;
        }
        _dict = new Dictionary<Tkey, Tvalue>();
    }

    public Tvalue this[Tkey key]
    {
        get
        {
            if (!_dict.ContainsKey(key))
            {
                _dict[key] = _getDefault();
            }
            return _dict[key];
        }

        set { _dict[key] = value; }
    }

    public bool ContainsKey(Tkey key)
    {
        return _dict.ContainsKey(key);
    }

    public override string ToString()
    {
        var sb = new StringBuilder();
        foreach (var kvp in _dict)
        {
            sb.AppendFormat("[{0}] : {1}", kvp.Key.ToString(), kvp.Value.ToString()).AppendLine();
        }

        return sb.ToString();
    }
}

Вы можете легко добавлять оболочки к другим методам и свойствам по мере необходимости.

0 голосов
/ 15 августа 2011

Я создал DefaultableDictionary в .NET, который делает именно то, что вы просите!

http://github.com/jsonmez/Defaultable-Dictionary

Блог здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...