开发者

.net dictionary with default value

I want a dictionary that would return a specified value for any key not in the开发者_Go百科 dictionary, something like:

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

Extending System.Collections.Generics.Dictionary and overriding TryGetValue doesn't work because TryGetValue isn't virtual.

Reimplementing Dictionary from scratch (from IDictionary<,>) is too much efforts.

Extension method won't let me "initialize" the dictionary with a default value. I want the consumer of dictionary to think that key is there, not just do dict.GetOrDefault(key, "not specified");


Reimplementing Dictionary from scratch (from IDictionary<,>) is too much efforts

This is really the best option. Just encapsulate a Dictionary<,> as a member of your class, and pass all members to the Dictionary's code. You only need to handle the properties and methods you wish to be different in that case.

I agree that it's a bit of tedious work - but it's probably less than 5 minutes worth of typing, since every method can be passed to the internal dictionary's implementation.


I think Reed is correct that Reimplementing Dictionary is pretty simple and if that's what you need that's fine.

but it still seems like overkill to create a new class to replace

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

with

      value  = dict.GetOrDefault(key, "not specified")


This extension method gets me through;

    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;
        }
    }

It's called like so;

dict.GetValueOrDefault("foo", 0) // returns the key under "foo", or 0 if missing.


I created a DefaultableDictionary in .NET that does exactly what you are asking for!

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

Blog post here.


Try this

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();
    }
}

You can easily add wrappers to the other methods and properties as needed.


I notice your example is a dictionary of Strings. It is also strings in my own scenario where I want similar behavior.

Perhaps the good old StringDictionary class will do what you want. Unlike Dictionary<string,string> its get_Item method returns null for keys which do not exist in the dictionary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜