/// <summary> /// Adds the values from the specified Dictionary to this dictionary's collection. /// </summary> /// <param name="source"></param> /// <param name="second">The dictionary to merge into this one.</param> /// <param name="mergeOptions">An enum which determines how merge conflicts should be handled.</param> /// <returns>The modified dictionary</returns> public static Dictionary <TKey, TValue> AddRange <TKey, TValue>(this Dictionary <TKey, TValue> source, Dictionary <TKey, TValue> second, DictionaryMergeOptions mergeOptions) { switch (mergeOptions) { case DictionaryMergeOptions.IgnoreDuplicates: foreach (var kvp in second) { if (!source.ContainsKey(kvp.Key)) { source.Add(kvp); } } break; case DictionaryMergeOptions.Overwrite: foreach (var kvp in second) { // Overwite the value if the key exists if (source.ContainsKey(kvp.Key)) { source[kvp.Key] = kvp.Value; } else { source.Add(kvp); } } break; case DictionaryMergeOptions.Throw: List <Exception> exceptions = new List <Exception>(); // In order to make this option atomic, we're just going to calculate var duplicates = source.Keys.Where(x => second.ContainsKey(x)); foreach (var key in duplicates) { exceptions.Add(new ArgumentException("Duplicate key found", nameof(key))); } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } else { foreach (var kvp in second) { source.Add(kvp); } } break; } return(source); }
/// <summary> /// Returns merged dictionaries, either ignoring duplicate keys or overwriting as specified by option parameter. /// NOTE: original dictionary will be modified (will be equal to return value) /// </summary> /// <param name="otherDict">Dictionary to merge into this one.</param> /// <param name="option">Overwrite duplicate keys or ignore them</param> public static IDictionary <TKey, TValue> MergeDictionary <TKey, TValue>(this IDictionary <TKey, TValue> original, IDictionary <TKey, TValue> otherDict, DictionaryMergeOptions option) { // If overwriting duplicates, do that first if (option == DictionaryMergeOptions.OverwriteDuplicateKey) { otherDict.Where(kv => original.ContainsKey(kv.Key)).ToList().ForEach(kv => original[kv.Key] = kv.Value); } // Add Missing otherDict.Where(kv => !original.ContainsKey(kv.Key)).ToList().ForEach(kv => original.Add(kv.Key, kv.Value)); return(original); }