using Masuit.Tools.Systems; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Masuit.Tools { public static class IDictionaryExtensions { /// /// 添加或更新键值对 /// /// /// 另一个字典集 public static void AddOrUpdate(this IDictionary @this, IDictionary that) { foreach (var item in that) { @this[item.Key] = item.Value; } } /// /// 添加或更新键值对 /// /// /// 另一个字典集 public static void AddOrUpdate(this NullableDictionary @this, IDictionary that) { foreach (var item in that) { @this[item.Key] = item.Value; } } /// /// 添加或更新键值对 /// /// /// 另一个字典集 public static void AddOrUpdate(this NullableConcurrentDictionary @this, IDictionary that) { foreach (var item in that) { @this[item.Key] = item.Value; } } /// /// 添加或更新键值对 /// /// /// 另一个字典集 public static void AddOrUpdateTo(this IDictionary @this, IDictionary that) { foreach (var item in @this) { that[item.Key] = item.Value; } } /// /// 添加或更新键值对 /// /// /// 另一个字典集 public static void AddOrUpdateTo(this NullableDictionary @this, IDictionary that) { foreach (var item in @this) { that[item.Key] = item.Value; } } /// /// 添加或更新键值对 /// /// /// 另一个字典集 public static void AddOrUpdateTo(this NullableConcurrentDictionary @this, IDictionary that) { foreach (var item in @this) { that[item.Key] = item.Value; } } /// /// 添加或更新键值对 /// /// /// 键 /// 添加时的值 /// 更新时的操作 public static TValue AddOrUpdate(this IDictionary @this, TKey key, TValue addValue, Func updateValueFactory) { if (!@this.TryAdd(key, addValue)) { @this[key] = updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// 键 /// 添加时的值 /// 更新时的操作 public static TValue AddOrUpdate(this NullableDictionary @this, TKey key, TValue addValue, Func updateValueFactory) { if (!@this.TryAdd(key, addValue)) { @this[key] = updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的值 /// 更新时的操作 public static TValue AddOrUpdate(this NullableConcurrentDictionary @this, TKey key, TValue addValue, Func updateValueFactory) { if (!@this.TryAdd(key, addValue)) { @this[key] = updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的值 /// 更新时的操作 public static async Task AddOrUpdateAsync(this IDictionary @this, TKey key, TValue addValue, Func> updateValueFactory) { if (!@this.TryAdd(key, addValue)) { @this[key] = await updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的值 /// 更新时的操作 public static async Task AddOrUpdateAsync(this NullableDictionary @this, TKey key, TValue addValue, Func> updateValueFactory) { if (!@this.TryAdd(key, addValue)) { @this[key] = await updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的值 /// 更新时的操作 public static async Task AddOrUpdateAsync(this NullableConcurrentDictionary @this, TKey key, TValue addValue, Func> updateValueFactory) { if (!@this.TryAdd(key, addValue)) { @this[key] = await updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的值 /// 更新时的值 public static TValue AddOrUpdate(this IDictionary @this, TKey key, TValue addValue, TValue updateValue) { if (!@this.TryAdd(key, addValue)) { @this[key] = updateValue; } return @this[key]; } /// /// 添加或更新键值对 /// /// /// 键 /// 添加时的值 /// 更新时的值 public static TValue AddOrUpdate(this NullableDictionary @this, TKey key, TValue addValue, TValue updateValue) { if (!@this.TryAdd(key, addValue)) { @this[key] = updateValue; } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的值 /// 更新时的值 public static TValue AddOrUpdate(this NullableConcurrentDictionary @this, TKey key, TValue addValue, TValue updateValue) { if (!@this.TryAdd(key, addValue)) { @this[key] = updateValue; } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static void AddOrUpdate(this IDictionary @this, IDictionary that, Func updateValueFactory) { foreach (var item in that) { AddOrUpdate(@this, item.Key, item.Value, updateValueFactory); } } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static void AddOrUpdate(this NullableDictionary @this, IDictionary that, Func updateValueFactory) { foreach (var item in that) { AddOrUpdate(@this, item.Key, item.Value, updateValueFactory); } } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static void AddOrUpdate(this NullableConcurrentDictionary @this, IDictionary that, Func updateValueFactory) { foreach (var item in that) { AddOrUpdate(@this, item.Key, item.Value, updateValueFactory); } } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static Task AddOrUpdateAsync(this IDictionary @this, IDictionary that, Func> updateValueFactory) { return that.ForeachAsync(item => AddOrUpdateAsync(@this, item.Key, item.Value, updateValueFactory)); } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static Task AddOrUpdateAsync(this NullableDictionary @this, IDictionary that, Func> updateValueFactory) { return that.ForeachAsync(item => AddOrUpdateAsync(@this, item.Key, item.Value, updateValueFactory)); } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static Task AddOrUpdateAsync(this NullableConcurrentDictionary @this, IDictionary that, Func> updateValueFactory) { return that.ForeachAsync(item => AddOrUpdateAsync(@this, item.Key, item.Value, updateValueFactory)); } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static void AddOrUpdateTo(this IDictionary @this, IDictionary that, Func updateValueFactory) { foreach (var item in @this) { AddOrUpdate(that, item.Key, item.Value, updateValueFactory); } } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static void AddOrUpdateTo(this IDictionary @this, NullableDictionary that, Func updateValueFactory) { foreach (var item in @this) { AddOrUpdate(that, item.Key, item.Value, updateValueFactory); } } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static void AddOrUpdateTo(this IDictionary @this, NullableConcurrentDictionary that, Func updateValueFactory) { foreach (var item in @this) { AddOrUpdate(that, item.Key, item.Value, updateValueFactory); } } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static Task AddOrUpdateAsyncTo(this IDictionary @this, IDictionary that, Func> updateValueFactory) { return @this.ForeachAsync(item => AddOrUpdateAsync(that, item.Key, item.Value, updateValueFactory)); } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static Task AddOrUpdateAsyncTo(this IDictionary @this, NullableDictionary that, Func> updateValueFactory) { return @this.ForeachAsync(item => AddOrUpdateAsync(that, item.Key, item.Value, updateValueFactory)); } /// /// 添加或更新键值对 /// /// /// /// /// 另一个字典集 /// 更新时的操作 public static Task AddOrUpdateAsyncTo(this IDictionary @this, NullableConcurrentDictionary that, Func> updateValueFactory) { return @this.ForeachAsync(item => AddOrUpdateAsync(that, item.Key, item.Value, updateValueFactory)); } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的操作 /// 更新时的操作 public static TValue AddOrUpdate(this IDictionary @this, TKey key, Func addValueFactory, Func updateValueFactory) { if (!@this.TryAdd(key, addValueFactory(key))) { @this[key] = updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的操作 /// 更新时的操作 public static TValue AddOrUpdate(this NullableDictionary @this, TKey key, Func addValueFactory, Func updateValueFactory) { if (!@this.TryAdd(key, addValueFactory(key))) { @this[key] = updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的操作 /// 更新时的操作 public static TValue AddOrUpdate(this NullableConcurrentDictionary @this, TKey key, Func addValueFactory, Func updateValueFactory) { if (!@this.TryAdd(key, addValueFactory(key))) { @this[key] = updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的操作 /// 更新时的操作 public static async Task AddOrUpdateAsync(this IDictionary @this, TKey key, Func> addValueFactory, Func> updateValueFactory) { if (!@this.TryAdd(key, await addValueFactory(key))) { @this[key] = await updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的操作 /// 更新时的操作 public static async Task AddOrUpdateAsync(this NullableDictionary @this, TKey key, Func> addValueFactory, Func> updateValueFactory) { if (!@this.TryAdd(key, await addValueFactory(key))) { @this[key] = await updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 添加或更新键值对 /// /// /// /// /// 键 /// 添加时的操作 /// 更新时的操作 public static async Task AddOrUpdateAsync(this NullableConcurrentDictionary @this, TKey key, Func> addValueFactory, Func> updateValueFactory) { if (!@this.TryAdd(key, await addValueFactory(key))) { @this[key] = await updateValueFactory(key, @this[key]); } return @this[key]; } /// /// 获取或添加 /// /// /// /// /// /// public static TValue GetOrAdd(this IDictionary @this, TKey key, Func addValueFactory) { if (!@this.ContainsKey(key)) { @this[key] = addValueFactory(); } return @this[key]; } /// /// 获取或添加 /// /// /// /// /// /// public static async Task GetOrAddAsync(this IDictionary @this, TKey key, Func> addValueFactory) { if (!@this.ContainsKey(key)) { @this[key] = await addValueFactory(); } return @this[key]; } /// /// 获取或添加 /// /// /// /// /// /// public static TValue GetOrAdd(this Dictionary @this, TKey key, TValue addValue) { return @this.TryAdd(key, addValue) ? addValue : @this[key]; } #if NETSTANDARD2_1_OR_GREATER #else public static bool TryAdd(this IDictionary dictionary, TKey key, TValue value) where TKey : notnull { if (dictionary == null) throw new ArgumentNullException(nameof(dictionary)); if (dictionary.IsReadOnly||dictionary.ContainsKey(key)) return false; dictionary.Add(key, value); return true; } #endif /// /// 遍历IEnumerable /// /// /// 回调方法 public static void ForEach(this IDictionary dic, Action action) { foreach (var item in dic) { action(item.Key, item.Value); } } /// /// 遍历IDictionary /// /// /// 回调方法 public static Task ForEachAsync(this IDictionary dic, Func action) { return dic.ForeachAsync(x => action(x.Key, x.Value)); } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 public static NullableDictionary ToDictionarySafety(this IEnumerable source, Func keySelector) { var items = source as IList ?? source.ToList(); var dic = new NullableDictionary(items.Count); foreach (var item in items) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 /// 键未找到时的默认值 public static NullableDictionary ToDictionarySafety(this IEnumerable source, Func keySelector, TSource defaultValue) { var items = source as IList ?? source.ToList(); var dic = new NullableDictionary(items.Count) { FallbackValue = defaultValue }; foreach (var item in items) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 public static NullableDictionary ToDictionarySafety(this IEnumerable source, Func keySelector, Func elementSelector) { var items = source as IList ?? source.ToList(); var dic = new NullableDictionary(items.Count); foreach (var item in items) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 /// 键未找到时的默认值 public static NullableDictionary ToDictionarySafety(this IEnumerable source, Func keySelector, Func elementSelector, TElement defaultValue) { var items = source as IList ?? source.ToList(); var dic = new NullableDictionary(items.Count) { FallbackValue = defaultValue }; foreach (var item in items) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 public static async Task> ToDictionarySafetyAsync(this IEnumerable source, Func keySelector, Func> elementSelector) { var items = source as IList ?? source.ToList(); var dic = new NullableDictionary(items.Count); await items.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 /// 键未找到时的默认值 public static async Task> ToDictionarySafetyAsync(this IEnumerable source, Func keySelector, Func> elementSelector, TElement defaultValue) { var items = source as IList ?? source.ToList(); var dic = new NullableDictionary(items.Count) { FallbackValue = defaultValue }; await items.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 public static DisposableDictionary ToDisposableDictionarySafety(this IEnumerable source, Func keySelector) where TSource : IDisposable { var items = source as IList ?? source.ToList(); var dic = new DisposableDictionary(items.Count); foreach (var item in items) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 /// 键未找到时的默认值 public static DisposableDictionary ToDisposableDictionarySafety(this IEnumerable source, Func keySelector, TSource defaultValue) where TSource : IDisposable { var items = source as IList ?? source.ToList(); var dic = new DisposableDictionary(items.Count) { FallbackValue = defaultValue }; foreach (var item in items) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 public static DisposableDictionary ToDisposableDictionarySafety(this IEnumerable source, Func keySelector, Func elementSelector) where TElement : IDisposable { var items = source as IList ?? source.ToList(); var dic = new DisposableDictionary(items.Count); foreach (var item in items) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 /// 键未找到时的默认值 public static DisposableDictionary ToDisposableDictionarySafety(this IEnumerable source, Func keySelector, Func elementSelector, TElement defaultValue) where TElement : IDisposable { var items = source as IList ?? source.ToList(); var dic = new DisposableDictionary(items.Count) { FallbackValue = defaultValue }; foreach (var item in items) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 public static async Task> ToDisposableDictionarySafetyAsync(this IEnumerable source, Func keySelector, Func> elementSelector) where TElement : IDisposable { var items = source as IList ?? source.ToList(); var dic = new DisposableDictionary(items.Count); await items.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 /// 键未找到时的默认值 public static async Task> ToDisposableDictionarySafetyAsync(this IEnumerable source, Func keySelector, Func> elementSelector, TElement defaultValue) where TElement : IDisposable { var items = source as IList ?? source.ToList(); var dic = new DisposableDictionary(items.Count) { FallbackValue = defaultValue }; await items.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 public static NullableConcurrentDictionary ToConcurrentDictionary(this IEnumerable source, Func keySelector) { var dic = new NullableConcurrentDictionary(); foreach (var item in source) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 /// 键未找到时的默认值 public static NullableConcurrentDictionary ToConcurrentDictionary(this IEnumerable source, Func keySelector, TSource defaultValue) { var dic = new NullableConcurrentDictionary() { FallbackValue = defaultValue }; foreach (var item in source) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 public static NullableConcurrentDictionary ToConcurrentDictionary(this IEnumerable source, Func keySelector, Func elementSelector) { var dic = new NullableConcurrentDictionary(); foreach (var item in source) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 /// public static NullableConcurrentDictionary ToConcurrentDictionary(this IEnumerable source, Func keySelector, Func elementSelector, TElement defaultValue) { var dic = new NullableConcurrentDictionary() { FallbackValue = defaultValue }; foreach (var item in source) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 public static async Task> ToConcurrentDictionaryAsync(this IEnumerable source, Func keySelector, Func> elementSelector) { var dic = new ConcurrentDictionary(); await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// /// 键选择器 /// 值选择器 /// 键未找到时的默认值 public static async Task> ToConcurrentDictionaryAsync(this IEnumerable source, Func keySelector, Func> elementSelector, TElement defaultValue) { var dic = new NullableConcurrentDictionary { FallbackValue = defaultValue }; await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// /// /// 键选择器 public static DisposableConcurrentDictionary ToDisposableConcurrentDictionary(this IEnumerable source, Func keySelector) where TSource : IDisposable { var dic = new DisposableConcurrentDictionary(); foreach (var item in source) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// 键选择器 /// 键未找到时的默认值 public static DisposableConcurrentDictionary ToDisposableConcurrentDictionary(this IEnumerable source, Func keySelector, TSource defaultValue) where TSource : IDisposable { var dic = new DisposableConcurrentDictionary { FallbackValue = defaultValue }; foreach (var item in source) { dic[keySelector(item)] = item; } return dic; } /// /// 安全的转换成字典集 /// /// /// 键选择器 /// 值选择器 public static DisposableConcurrentDictionary ToDisposableConcurrentDictionary(this IEnumerable source, Func keySelector, Func elementSelector) where TElement : IDisposable { var dic = new DisposableConcurrentDictionary(); foreach (var item in source) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// 键选择器 /// 值选择器 /// public static DisposableConcurrentDictionary ToDisposableConcurrentDictionary(this IEnumerable source, Func keySelector, Func elementSelector, TElement defaultValue) where TElement : IDisposable { var dic = new DisposableConcurrentDictionary() { FallbackValue = defaultValue }; foreach (var item in source) { dic[keySelector(item)] = elementSelector(item); } return dic; } /// /// 安全的转换成字典集 /// /// /// 键选择器 /// 值选择器 public static async Task> ToDisposableConcurrentDictionaryAsync(this IEnumerable source, Func keySelector, Func> elementSelector) where TElement : IDisposable { var dic = new DisposableConcurrentDictionary(); await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 安全的转换成字典集 /// /// /// 键选择器 /// 值选择器 /// 键未找到时的默认值 public static async Task> ToDisposableConcurrentDictionaryAsync(this IEnumerable source, Func keySelector, Func> elementSelector, TElement defaultValue) where TElement : IDisposable { var dic = new DisposableConcurrentDictionary() { FallbackValue = defaultValue }; await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item)); return dic; } /// /// 转换成并发字典集合 /// public static NullableConcurrentDictionary AsConcurrentDictionary(this Dictionary dic) => dic; /// /// 转换成并发字典集合 /// /// /// 键未找到时的默认值 public static NullableConcurrentDictionary AsConcurrentDictionary(this Dictionary dic, TValue defaultValue) { var nullableDictionary = new NullableConcurrentDictionary() { FallbackValue = defaultValue }; foreach (var p in dic) { nullableDictionary[p.Key] = p.Value; } return nullableDictionary; } /// /// 转换成普通字典集合 /// public static NullableDictionary AsDictionary(this ConcurrentDictionary dic) => dic; /// /// 转换成普通字典集合 /// /// /// 键未找到时的默认值 public static NullableDictionary AsDictionary(this ConcurrentDictionary dic, TValue defaultValue) { var nullableDictionary = new NullableDictionary() { FallbackValue = defaultValue }; foreach (var p in dic) { nullableDictionary[p.Key] = p.Value; } return nullableDictionary; } } }