.NET Dictionary: get or create new

后端 未结 8 1739
感情败类
感情败类 2020-12-08 13:38

I often find myself creating a Dictionary with a non-trivial value class (e.g. List), and then always writing the same code pattern when filling in data.

For example

8条回答
  •  执笔经年
    2020-12-08 13:48

    For further readers, here are some extensions in every flavour I thought fit. You could also do something with an out parameter if you need to check if you have added a value but i think you can use containskey or something already for that.

    You can use GetOrAddNew to retrieve an item, or create and add it to the dict. You can use the various overloads of GetOrAdd to add a new value. This could be the default so e.g. NULL or 0 but you can also provide a lambda to construct an object for you, with any kind of constructor arguments you'd like.

    var x = new Dictionary();
    var val = x.GetOrAdd("MyKey", (dict, key) => dict.Count + 2);
    var val2 = x.GetOrAdd("MyKey", () => Convert.ToInt32("2"));
    var val3 = x.GetOrAdd("MyKey", 1);
    
        /// 
        /// Extensions for dealing with 
        /// 
        public static class DictionaryExtensions
        {
            public static TValue GetOrAddNew(this IDictionary dict, TKey key, TValue defaultValue = default) 
                where TValue : new() 
                => dict.GetOrAdd(key, (values, innerKey) => EqualityComparer.Default.Equals(default(TValue), defaultValue) ? new TValue() : defaultValue);
    
            public static TValue GetOrAdd(this IDictionary dict, TKey key, TValue defaultValue = default)
                => dict.GetOrAdd(key, (values, innerKey) => defaultValue);
    
            public static TValue GetOrAdd(this IDictionary dict, TKey key, Func valueProvider)
                => dict.GetOrAdd(key, (values, innerKey) => valueProvider());
    
            public static TValue GetOrAdd(this IDictionary dict, TKey key, Func valueProvider)
                => dict.GetOrAdd(key, (values, innerKey) => valueProvider(key));
    
            public static TValue GetOrAdd(this IDictionary dict, TKey key, Func, TKey, TValue> valueProvider)
            {
                if (dict == null) throw new ArgumentNullException(nameof(dict));
                if (key == null) throw new ArgumentNullException(nameof(key));
                if (valueProvider == null) throw new ArgumentNullException(nameof(valueProvider));
    
                if (dict.TryGetValue(key, out var foundValue))
                    return foundValue;
    
                dict[key] = valueProvider(dict, key);
                return dict[key];
            }
        }
    

提交回复
热议问题