IDictionaryExtensions.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. using Masuit.Tools.Systems;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.Threading.Tasks;
  6. namespace Masuit.Tools
  7. {
  8. public static class IDictionaryExtensions
  9. {
  10. /// <summary>
  11. /// 添加或更新键值对
  12. /// </summary>
  13. /// <typeparam name="TKey"></typeparam>
  14. /// <typeparam name="TValue"></typeparam>
  15. /// <param name="this"></param>
  16. /// <param name="that">另一个字典集</param>
  17. /// <returns></returns>
  18. public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that)
  19. {
  20. foreach (var item in that)
  21. {
  22. @this[item.Key] = item.Value;
  23. }
  24. }
  25. /// <summary>
  26. /// 添加或更新键值对
  27. /// </summary>
  28. /// <typeparam name="TKey"></typeparam>
  29. /// <typeparam name="TValue"></typeparam>
  30. /// <param name="this"></param>
  31. /// <param name="that">另一个字典集</param>
  32. /// <returns></returns>
  33. public static void AddOrUpdate<TKey, TValue>(this NullableConcurrentDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that)
  34. {
  35. foreach (var item in that)
  36. {
  37. @this[item.Key] = item.Value;
  38. }
  39. }
  40. /// <summary>
  41. /// 添加或更新键值对
  42. /// </summary>
  43. /// <typeparam name="TKey"></typeparam>
  44. /// <typeparam name="TValue"></typeparam>
  45. /// <param name="this"></param>
  46. /// <param name="that">另一个字典集</param>
  47. /// <returns></returns>
  48. public static void AddOrUpdateTo<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that)
  49. {
  50. foreach (var item in @this)
  51. {
  52. that[item.Key] = item.Value;
  53. }
  54. }
  55. /// <summary>
  56. /// 添加或更新键值对
  57. /// </summary>
  58. /// <typeparam name="TKey"></typeparam>
  59. /// <typeparam name="TValue"></typeparam>
  60. /// <param name="this"></param>
  61. /// <param name="key">键</param>
  62. /// <param name="addValue">添加时的值</param>
  63. /// <param name="updateValueFactory">更新时的操作</param>
  64. /// <returns></returns>
  65. public static TValue AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
  66. {
  67. if ([email protected](key))
  68. {
  69. @this.Add(key, addValue);
  70. }
  71. else
  72. {
  73. @this[key] = updateValueFactory(key, @this[key]);
  74. }
  75. return @this[key];
  76. }
  77. /// <summary>
  78. /// 添加或更新键值对
  79. /// </summary>
  80. /// <typeparam name="TKey"></typeparam>
  81. /// <typeparam name="TValue"></typeparam>
  82. /// <param name="this"></param>
  83. /// <param name="key">键</param>
  84. /// <param name="addValue">添加时的值</param>
  85. /// <param name="updateValueFactory">更新时的操作</param>
  86. /// <returns></returns>
  87. public static async Task<TValue> AddOrUpdateAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue, Func<TKey, TValue, Task<TValue>> updateValueFactory)
  88. {
  89. if ([email protected](key))
  90. {
  91. @this.Add(key, addValue);
  92. }
  93. else
  94. {
  95. @this[key] = await updateValueFactory(key, @this[key]);
  96. }
  97. return @this[key];
  98. }
  99. /// <summary>
  100. /// 添加或更新键值对
  101. /// </summary>
  102. /// <typeparam name="TKey"></typeparam>
  103. /// <typeparam name="TValue"></typeparam>
  104. /// <param name="this"></param>
  105. /// <param name="key">键</param>
  106. /// <param name="addValue">添加时的值</param>
  107. /// <param name="updateValue">更新时的值</param>
  108. /// <returns></returns>
  109. public static TValue AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue, TValue updateValue)
  110. {
  111. if ([email protected](key))
  112. {
  113. @this.Add(key, addValue);
  114. }
  115. else
  116. {
  117. @this[key] = updateValue;
  118. }
  119. return @this[key];
  120. }
  121. /// <summary>
  122. /// 添加或更新键值对
  123. /// </summary>
  124. /// <typeparam name="TKey"></typeparam>
  125. /// <typeparam name="TValue"></typeparam>
  126. /// <param name="this"></param>
  127. /// <param name="that">另一个字典集</param>
  128. /// <param name="updateValueFactory">更新时的操作</param>
  129. /// <returns></returns>
  130. public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, TValue> updateValueFactory)
  131. {
  132. foreach (var item in that)
  133. {
  134. AddOrUpdate(@this, item.Key, item.Value, updateValueFactory);
  135. }
  136. }
  137. /// <summary>
  138. /// 添加或更新键值对
  139. /// </summary>
  140. /// <typeparam name="TKey"></typeparam>
  141. /// <typeparam name="TValue"></typeparam>
  142. /// <param name="this"></param>
  143. /// <param name="that">另一个字典集</param>
  144. /// <param name="updateValueFactory">更新时的操作</param>
  145. /// <returns></returns>
  146. public static Task AddOrUpdateAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, Task<TValue>> updateValueFactory)
  147. {
  148. return that.ForeachAsync(item => AddOrUpdateAsync(@this, item.Key, item.Value, updateValueFactory));
  149. }
  150. /// <summary>
  151. /// 添加或更新键值对
  152. /// </summary>
  153. /// <typeparam name="TKey"></typeparam>
  154. /// <typeparam name="TValue"></typeparam>
  155. /// <param name="this"></param>
  156. /// <param name="that">另一个字典集</param>
  157. /// <param name="updateValueFactory">更新时的操作</param>
  158. /// <returns></returns>
  159. public static void AddOrUpdateTo<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, TValue> updateValueFactory)
  160. {
  161. foreach (var item in @this)
  162. {
  163. AddOrUpdate(that, item.Key, item.Value, updateValueFactory);
  164. }
  165. }
  166. /// <summary>
  167. /// 添加或更新键值对
  168. /// </summary>
  169. /// <typeparam name="TKey"></typeparam>
  170. /// <typeparam name="TValue"></typeparam>
  171. /// <param name="this"></param>
  172. /// <param name="that">另一个字典集</param>
  173. /// <param name="updateValueFactory">更新时的操作</param>
  174. /// <returns></returns>
  175. public static Task AddOrUpdateAsyncTo<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, Task<TValue>> updateValueFactory)
  176. {
  177. return @this.ForeachAsync(item => AddOrUpdateAsync(that, item.Key, item.Value, updateValueFactory));
  178. }
  179. /// <summary>
  180. /// 添加或更新键值对
  181. /// </summary>
  182. /// <typeparam name="TKey"></typeparam>
  183. /// <typeparam name="TValue"></typeparam>
  184. /// <param name="this"></param>
  185. /// <param name="key">键</param>
  186. /// <param name="addValueFactory">添加时的操作</param>
  187. /// <param name="updateValueFactory">更新时的操作</param>
  188. /// <returns></returns>
  189. public static TValue AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
  190. {
  191. if ([email protected](key))
  192. {
  193. @this.Add(key, addValueFactory(key));
  194. }
  195. else
  196. {
  197. @this[key] = updateValueFactory(key, @this[key]);
  198. }
  199. return @this[key];
  200. }
  201. /// <summary>
  202. /// 添加或更新键值对
  203. /// </summary>
  204. /// <typeparam name="TKey"></typeparam>
  205. /// <typeparam name="TValue"></typeparam>
  206. /// <param name="this"></param>
  207. /// <param name="key">键</param>
  208. /// <param name="addValueFactory">添加时的操作</param>
  209. /// <param name="updateValueFactory">更新时的操作</param>
  210. /// <returns></returns>
  211. public static async Task<TValue> AddOrUpdateAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<TKey, Task<TValue>> addValueFactory, Func<TKey, TValue, Task<TValue>> updateValueFactory)
  212. {
  213. if ([email protected](key))
  214. {
  215. @this.Add(key, await addValueFactory(key));
  216. }
  217. else
  218. {
  219. @this[key] = await updateValueFactory(key, @this[key]);
  220. }
  221. return @this[key];
  222. }
  223. /// <summary>
  224. /// 获取或添加
  225. /// </summary>
  226. /// <typeparam name="TKey"></typeparam>
  227. /// <typeparam name="TValue"></typeparam>
  228. /// <param name="this"></param>
  229. /// <param name="key"></param>
  230. /// <param name="addValueFactory"></param>
  231. /// <returns></returns>
  232. public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<TValue> addValueFactory)
  233. {
  234. if ([email protected](key))
  235. {
  236. @this.Add(key, addValueFactory());
  237. }
  238. return @this[key];
  239. }
  240. /// <summary>
  241. /// 获取或添加
  242. /// </summary>
  243. /// <typeparam name="TKey"></typeparam>
  244. /// <typeparam name="TValue"></typeparam>
  245. /// <param name="this"></param>
  246. /// <param name="key"></param>
  247. /// <param name="addValueFactory"></param>
  248. /// <returns></returns>
  249. public static async Task<TValue> GetOrAddAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<Task<TValue>> addValueFactory)
  250. {
  251. if ([email protected](key))
  252. {
  253. @this.Add(key, await addValueFactory());
  254. }
  255. return @this[key];
  256. }
  257. /// <summary>
  258. /// 获取或添加
  259. /// </summary>
  260. /// <typeparam name="TKey"></typeparam>
  261. /// <typeparam name="TValue"></typeparam>
  262. /// <param name="this"></param>
  263. /// <param name="key"></param>
  264. /// <param name="addValue"></param>
  265. /// <returns></returns>
  266. public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue)
  267. {
  268. if ([email protected](key))
  269. {
  270. @this.Add(key, addValue);
  271. }
  272. return @this[key];
  273. }
  274. /// <summary>
  275. /// 遍历IEnumerable
  276. /// </summary>
  277. /// <param name="dic"></param>
  278. /// <param name="action">回调方法</param>
  279. public static void ForEach<TKey, TValue>(this IDictionary<TKey, TValue> dic, Action<TKey, TValue> action)
  280. {
  281. foreach (var item in dic)
  282. {
  283. action(item.Key, item.Value);
  284. }
  285. }
  286. /// <summary>
  287. /// 遍历IDictionary
  288. /// </summary>
  289. /// <param name="dic"></param>
  290. /// <param name="action">回调方法</param>
  291. public static Task ForEachAsync<TKey, TValue>(this IDictionary<TKey, TValue> dic, Func<TKey, TValue, Task> action)
  292. {
  293. return dic.ForeachAsync(x => action(x.Key, x.Value));
  294. }
  295. /// <summary>
  296. /// 安全的转换成字典集
  297. /// </summary>
  298. /// <typeparam name="TSource"></typeparam>
  299. /// <typeparam name="TKey"></typeparam>
  300. /// <param name="source"></param>
  301. /// <param name="keySelector">键选择器</param>
  302. /// <returns></returns>
  303. public static NullableDictionary<TKey, TSource> ToDictionarySafety<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  304. {
  305. var dic = new Dictionary<TKey, TSource>();
  306. foreach (var item in source)
  307. {
  308. dic[keySelector(item)] = item;
  309. }
  310. return dic;
  311. }
  312. /// <summary>
  313. /// 安全的转换成字典集
  314. /// </summary>
  315. /// <typeparam name="TSource"></typeparam>
  316. /// <typeparam name="TKey"></typeparam>
  317. /// <typeparam name="TElement"></typeparam>
  318. /// <param name="source"></param>
  319. /// <param name="keySelector">键选择器</param>
  320. /// <param name="elementSelector">值选择器</param>
  321. /// <returns></returns>
  322. public static NullableDictionary<TKey, TElement> ToDictionarySafety<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
  323. {
  324. var dic = new NullableDictionary<TKey, TElement>();
  325. foreach (var item in source)
  326. {
  327. dic[keySelector(item)] = elementSelector(item);
  328. }
  329. return dic;
  330. }
  331. /// <summary>
  332. /// 安全的转换成字典集
  333. /// </summary>
  334. /// <typeparam name="TSource"></typeparam>
  335. /// <typeparam name="TKey"></typeparam>
  336. /// <typeparam name="TElement"></typeparam>
  337. /// <param name="source"></param>
  338. /// <param name="keySelector">键选择器</param>
  339. /// <param name="elementSelector">值选择器</param>
  340. /// <returns></returns>
  341. public static async Task<NullableConcurrentDictionary<TKey, TElement>> ToDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector)
  342. {
  343. var dic = new NullableConcurrentDictionary<TKey, TElement>();
  344. await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
  345. return dic;
  346. }
  347. /// <summary>
  348. /// 安全的转换成字典集
  349. /// </summary>
  350. /// <typeparam name="TSource"></typeparam>
  351. /// <typeparam name="TKey"></typeparam>
  352. /// <typeparam name="TElement"></typeparam>
  353. /// <param name="source"></param>
  354. /// <param name="keySelector">键选择器</param>
  355. /// <returns></returns>
  356. public static NullableConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  357. {
  358. var dic = new NullableConcurrentDictionary<TKey, TSource>();
  359. foreach (var item in source)
  360. {
  361. dic[keySelector(item)] = item;
  362. }
  363. return dic;
  364. }
  365. /// <summary>
  366. /// 安全的转换成字典集
  367. /// </summary>
  368. /// <typeparam name="TSource"></typeparam>
  369. /// <typeparam name="TKey"></typeparam>
  370. /// <typeparam name="TElement"></typeparam>
  371. /// <param name="source"></param>
  372. /// <param name="keySelector">键选择器</param>
  373. /// <param name="elementSelector">值选择器</param>
  374. /// <returns></returns>
  375. public static NullableConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
  376. {
  377. var dic = new NullableConcurrentDictionary<TKey, TElement>();
  378. foreach (var item in source)
  379. {
  380. dic[keySelector(item)] = elementSelector(item);
  381. }
  382. return dic;
  383. }
  384. /// <summary>
  385. /// 安全的转换成字典集
  386. /// </summary>
  387. /// <typeparam name="TSource"></typeparam>
  388. /// <typeparam name="TKey"></typeparam>
  389. /// <typeparam name="TElement"></typeparam>
  390. /// <param name="source"></param>
  391. /// <param name="keySelector">键选择器</param>
  392. /// <param name="elementSelector">值选择器</param>
  393. /// <returns></returns>
  394. public static async Task<NullableConcurrentDictionary<TKey, TElement>> ToConcurrentDictionaryAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector)
  395. {
  396. var dic = new ConcurrentDictionary<TKey, TElement>();
  397. await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
  398. return dic;
  399. }
  400. /// <summary>
  401. /// 转换成并发字典集合
  402. /// </summary>
  403. /// <typeparam name="TKey"></typeparam>
  404. /// <typeparam name="TValue"></typeparam>
  405. /// <param name="dic"></param>
  406. /// <returns></returns>
  407. public static NullableConcurrentDictionary<TKey, TValue> AsConcurrentDictionary<TKey, TValue>(this Dictionary<TKey, TValue> dic) => dic;
  408. /// <summary>
  409. /// 转换成普通字典集合
  410. /// </summary>
  411. /// <typeparam name="TKey"></typeparam>
  412. /// <typeparam name="TValue"></typeparam>
  413. /// <param name="dic"></param>
  414. /// <returns></returns>
  415. public static NullableDictionary<TKey, TValue> AsDictionary<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dic) => dic;
  416. }
  417. }