咨询区
Custodio:
我一直都有一个疑惑?那就是为啥 Dictionary 不提供 AddRange 方法呢?
回答区
Rafal Zajac:
我觉得 Dictionary 之所以没有提供 AddRange
方法,主要还是考虑当遇到重复key的时候该如何处理?比如下面四种情况:
忽略
A 和 B 重复,忽略 B 。
覆盖
A 和 B 重复,覆盖 A。
合并
A 和 B 重复,将 key 的 value 进行合并。
异常
A 和 B 重复,抛异常给用户处理。
当然这也不是多难得事情,我自己就封装一个 AddRange 的扩展方法,代码如下:
namespace MyProject.Helper
{public static class CollectionHelper{public static void AddRangeOverride<TKey, TValue>(this IDictionary<TKey, TValue> dic, IDictionary<TKey, TValue> dicToAdd){dicToAdd.ForEach(x => dic[x.Key] = x.Value);}public static void AddRangeNewOnly<TKey, TValue>(this IDictionary<TKey, TValue> dic, IDictionary<TKey, TValue> dicToAdd){dicToAdd.ForEach(x => { if (!dic.ContainsKey(x.Key)) dic.Add(x.Key, x.Value); });}public static void AddRange<TKey, TValue>(this IDictionary<TKey, TValue> dic, IDictionary<TKey, TValue> dicToAdd){dicToAdd.ForEach(x => dic.Add(x.Key, x.Value));}public static bool ContainsKeys<TKey, TValue>(this IDictionary<TKey, TValue> dic, IEnumerable<TKey> keys){bool result = false;keys.ForEachOrBreak((x) => { result = dic.ContainsKey(x); return result; });return result;}public static void ForEach<T>(this IEnumerable<T> source, Action<T> action){foreach (var item in source)action(item);}public static void ForEachOrBreak<T>(this IEnumerable<T> source, Func<T, bool> func){foreach (var item in source){bool result = func(item);if (result) break;}}}
}
然后像下面这样使用。
Dictionary<string, string> mainDic = new Dictionary<string, string>() { { "Key1", "Value1" },{ "Key2", "Value2.1" },
};
Dictionary<string, string> additionalDic= new Dictionary<string, string>() { { "Key2", "Value2.2" },{ "Key3", "Value3" },
};
mainDic.AddRangeOverride(additionalDic); // Overrides all existing keys
// or
mainDic.AddRangeNewOnly(additionalDic); // Adds new keys only
// or
mainDic.AddRange(additionalDic); // Throws an error if keys already exist
// or
if (!mainDic.ContainsKeys(additionalDic.Keys)) // Checks if keys don't exist
{mainDic.AddRange(additionalDic);
}
点评区
我个人觉得 Dictionary 中应该要提供一个 AddRange 方法,然后通过枚举的方式指定下遇到重复key的情况该执行什么路径,可能现有的扩展方法太多了,没有 AddRange 也可以轻松实现。