Bläddra i källkod

增加Dictionary扩展函数

懒得勤快 3 år sedan
förälder
incheckning
cba72fe01f

+ 241 - 8
Masuit.Tools.Abstractions/Extensions/BaseType/IDictionaryExtensions.cs

@@ -2,6 +2,7 @@
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 
 namespace Masuit.Tools
@@ -328,7 +329,7 @@ namespace Masuit.Tools
         /// <returns></returns>
         public static NullableDictionary<TKey, TSource> ToDictionarySafety<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
-            var dic = new NullableDictionary<TKey, TSource>();
+            var dic = new NullableDictionary<TKey, TSource>(source.Count());
             foreach (var item in source)
             {
                 dic[keySelector(item)] = item;
@@ -348,7 +349,7 @@ namespace Masuit.Tools
         /// <returns></returns>
         public static NullableDictionary<TKey, TSource> ToDictionarySafety<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, TSource defaultValue)
         {
-            var dic = new NullableDictionary<TKey, TSource>() { FallbackValue = defaultValue };
+            var dic = new NullableDictionary<TKey, TSource>(source.Count()) { FallbackValue = defaultValue };
             foreach (var item in source)
             {
                 dic[keySelector(item)] = item;
@@ -369,7 +370,7 @@ namespace Masuit.Tools
         /// <returns></returns>
         public static NullableDictionary<TKey, TElement> ToDictionarySafety<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
         {
-            var dic = new NullableDictionary<TKey, TElement>();
+            var dic = new NullableDictionary<TKey, TElement>(source.Count());
             foreach (var item in source)
             {
                 dic[keySelector(item)] = elementSelector(item);
@@ -391,7 +392,7 @@ namespace Masuit.Tools
         /// <returns></returns>
         public static NullableDictionary<TKey, TElement> ToDictionarySafety<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, TElement defaultValue)
         {
-            var dic = new NullableDictionary<TKey, TElement>() { FallbackValue = defaultValue };
+            var dic = new NullableDictionary<TKey, TElement>(source.Count()) { FallbackValue = defaultValue };
             foreach (var item in source)
             {
                 dic[keySelector(item)] = elementSelector(item);
@@ -410,9 +411,9 @@ namespace Masuit.Tools
         /// <param name="keySelector">键选择器</param>
         /// <param name="elementSelector">值选择器</param>
         /// <returns></returns>
-        public static async Task<NullableConcurrentDictionary<TKey, TElement>> ToDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector)
+        public static async Task<NullableDictionary<TKey, TElement>> ToDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector)
         {
-            var dic = new NullableConcurrentDictionary<TKey, TElement>();
+            var dic = new NullableDictionary<TKey, TElement>(source.Count());
             await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
             return dic;
         }
@@ -428,13 +429,52 @@ namespace Masuit.Tools
         /// <param name="elementSelector">值选择器</param>
         /// <param name="defaultValue">键未找到时的默认值</param>
         /// <returns></returns>
-        public static async Task<NullableConcurrentDictionary<TKey, TElement>> ToDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector, TElement defaultValue)
+        public static async Task<NullableDictionary<TKey, TElement>> ToDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector, TElement defaultValue)
         {
-            var dic = new NullableConcurrentDictionary<TKey, TElement>() { FallbackValue = defaultValue };
+            var dic = new NullableDictionary<TKey, TElement>(source.Count()) { FallbackValue = defaultValue };
             await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
             return dic;
         }
 
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <returns></returns>
+        public static DisposableDictionary<TKey, TSource> ToDisposableDictionarySafety<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) where TSource : IDisposable
+        {
+            var dic = new DisposableDictionary<TKey, TSource>(source.Count());
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = item;
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="defaultValue">键未找到时的默认值</param>
+        /// <returns></returns>
+        public static DisposableDictionary<TKey, TSource> ToDisposableDictionarySafety<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, TSource defaultValue) where TSource : IDisposable
+        {
+            var dic = new DisposableDictionary<TKey, TSource>(source.Count()) { FallbackValue = defaultValue };
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = item;
+            }
+
+            return dic;
+        }
+
         /// <summary>
         /// 安全的转换成字典集
         /// </summary>
@@ -443,6 +483,83 @@ namespace Masuit.Tools
         /// <typeparam name="TElement"></typeparam>
         /// <param name="source"></param>
         /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <returns></returns>
+        public static DisposableDictionary<TKey, TElement> ToDisposableDictionarySafety<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) where TElement : IDisposable
+        {
+            var dic = new DisposableDictionary<TKey, TElement>(source.Count());
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = elementSelector(item);
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <param name="defaultValue">键未找到时的默认值</param>
+        /// <returns></returns>
+        public static DisposableDictionary<TKey, TElement> ToDisposableDictionarySafety<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, TElement defaultValue) where TElement : IDisposable
+        {
+            var dic = new DisposableDictionary<TKey, TElement>(source.Count()) { FallbackValue = defaultValue };
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = elementSelector(item);
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <returns></returns>
+        public static async Task<DisposableDictionary<TKey, TElement>> ToDisposableDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector) where TElement : IDisposable
+        {
+            var dic = new DisposableDictionary<TKey, TElement>(source.Count());
+            await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <param name="defaultValue">键未找到时的默认值</param>
+        /// <returns></returns>
+        public static async Task<DisposableDictionary<TKey, TElement>> ToDisposableDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector, TElement defaultValue) where TElement : IDisposable
+        {
+            var dic = new DisposableDictionary<TKey, TElement>(source.Count()) { FallbackValue = defaultValue };
+            await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
         /// <returns></returns>
         public static NullableConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
         {
@@ -552,6 +669,122 @@ namespace Masuit.Tools
             return dic;
         }
 
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <returns></returns>
+        public static DisposableConcurrentDictionary<TKey, TSource> ToDisposableConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) where TSource : IDisposable
+        {
+            var dic = new DisposableConcurrentDictionary<TKey, TSource>();
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = item;
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="defaultValue">键未找到时的默认值</param>
+        /// <returns></returns>
+        public static DisposableConcurrentDictionary<TKey, TSource> ToDisposableConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, TSource defaultValue) where TSource : IDisposable
+        {
+            var dic = new DisposableConcurrentDictionary<TKey, TSource>() { FallbackValue = defaultValue };
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = item;
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <returns></returns>
+        public static DisposableConcurrentDictionary<TKey, TElement> ToDisposableConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) where TElement : IDisposable
+        {
+            var dic = new DisposableConcurrentDictionary<TKey, TElement>();
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = elementSelector(item);
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <returns></returns>
+        public static DisposableConcurrentDictionary<TKey, TElement> ToDisposableConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, TElement defaultValue) where TElement : IDisposable
+        {
+            var dic = new DisposableConcurrentDictionary<TKey, TElement>() { FallbackValue = defaultValue };
+            foreach (var item in source)
+            {
+                dic[keySelector(item)] = elementSelector(item);
+            }
+
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <returns></returns>
+        public static async Task<DisposableConcurrentDictionary<TKey, TElement>> ToDisposableConcurrentDictionaryAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector) where TElement : IDisposable
+        {
+            var dic = new DisposableConcurrentDictionary<TKey, TElement>();
+            await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
+            return dic;
+        }
+
+        /// <summary>
+        /// 安全的转换成字典集
+        /// </summary>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TKey"></typeparam>
+        /// <typeparam name="TElement"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="keySelector">键选择器</param>
+        /// <param name="elementSelector">值选择器</param>
+        /// <param name="defaultValue">键未找到时的默认值</param>
+        /// <returns></returns>
+        public static async Task<DisposableConcurrentDictionary<TKey, TElement>> ToDisposableConcurrentDictionaryAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector, TElement defaultValue) where TElement : IDisposable
+        {
+            var dic = new DisposableConcurrentDictionary<TKey, TElement>() { FallbackValue = defaultValue };
+            await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
+            return dic;
+        }
+
         /// <summary>
         /// 转换成并发字典集合
         /// </summary>

+ 2 - 2
Masuit.Tools.Abstractions/Files/ISevenZipCompressor.cs

@@ -34,7 +34,7 @@ namespace Masuit.Tools.Files
         /// <param name="zipFile">压缩到...</param>
         /// <param name="archiveType"></param>
         /// <param name="disposeAllStreams">是否需要释放所有流</param>
-        void Zip(DisposeableDictionary<string, Stream> streams, string zipFile, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false);
+        void Zip(DisposableDictionary<string, Stream> streams, string zipFile, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false);
 
         /// <summary>
         /// 将多个文件压缩到一个文件流中,可保存为zip文件,方便于web方式下载
@@ -52,6 +52,6 @@ namespace Masuit.Tools.Files
         /// <param name="archiveType"></param>
         /// <param name="disposeAllStreams">是否需要释放所有流</param>
         /// <returns>文件流</returns>
-        MemoryStream ZipStream(DisposeableDictionary<string, Stream> streams, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false);
+        MemoryStream ZipStream(DisposableDictionary<string, Stream> streams, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false);
     }
 }

+ 2 - 2
Masuit.Tools.Abstractions/Files/SevenZipCompressor.cs

@@ -59,7 +59,7 @@ namespace Masuit.Tools.Files
         /// <param name="archiveType"></param>
         /// <param name="disposeAllStreams">是否需要释放所有流</param>
         /// <returns>文件流</returns>
-        public MemoryStream ZipStream(DisposeableDictionary<string, Stream> streams, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
+        public MemoryStream ZipStream(DisposableDictionary<string, Stream> streams, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
         {
             using var archive = ArchiveFactory.Create(archiveType);
             foreach (var pair in streams)
@@ -110,7 +110,7 @@ namespace Masuit.Tools.Files
         /// <param name="zipFile">压缩到...</param>
         /// <param name="archiveType"></param>
         /// <param name="disposeAllStreams">是否需要释放所有流</param>
-        public void Zip(DisposeableDictionary<string, Stream> streams, string zipFile, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
+        public void Zip(DisposableDictionary<string, Stream> streams, string zipFile, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
         {
             using var archive = ArchiveFactory.Create(archiveType);
             foreach (var pair in streams)

+ 3 - 3
Masuit.Tools.Abstractions/Masuit.Tools.Abstractions.csproj

@@ -4,7 +4,7 @@
     <LangVersion>latest</LangVersion>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <CodeAnalysisRuleSet />
-    <Version>2.4.9.2</Version>
+    <Version>2.4.9.3</Version>
     <Authors>懒得勤快</Authors>
     <Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
     <Copyright>懒得勤快,长空X</Copyright>
@@ -42,14 +42,14 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="DnsClient" Version="1.6.0" />
+    <PackageReference Include="DnsClient" Version="1.6.1" />
     <PackageReference Include="HtmlSanitizer" Version="7.1.512" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
     <PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
     <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.7.0" />
     <PackageReference Include="System.Management" Version="4.7.0" />
     <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
-        <PackageReference Include="SharpCompress" Version="0.31.0" />
+        <PackageReference Include="SharpCompress" Version="0.32.0" />
   </ItemGroup>
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">

+ 62 - 0
Masuit.Tools.Abstractions/Systems/DisposableConcurrentDictionary.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Masuit.Tools.Systems;
+
+/// <summary>
+/// 值可被Dispose的字典类型
+/// </summary>
+/// <typeparam name="TKey"></typeparam>
+/// <typeparam name="TValue"></typeparam>
+public class DisposableConcurrentDictionary<TKey, TValue> : NullableConcurrentDictionary<TKey, TValue>, IDisposable where TValue : IDisposable
+{
+    private bool _isDisposed;
+
+    /// <summary>
+    /// 终结器
+    /// </summary>
+    ~DisposableConcurrentDictionary()
+    {
+        Dispose(false);
+    }
+
+    public DisposableConcurrentDictionary() : base()
+    {
+    }
+
+    public DisposableConcurrentDictionary(int concurrencyLevel, int capacity) : base(concurrencyLevel, capacity)
+    {
+    }
+
+    public DisposableConcurrentDictionary(IEqualityComparer<NullObject<TKey>> comparer) : base(comparer)
+    {
+    }
+
+    /// <summary>
+    ///
+    /// </summary>
+    public void Dispose()
+    {
+        if (_isDisposed)
+        {
+            return;
+        }
+
+        Dispose(true);
+        _isDisposed = true;
+        GC.SuppressFinalize(this);
+    }
+
+    /// <summary>
+    /// 释放
+    /// </summary>
+    /// <param name="disposing"></param>
+    public void Dispose(bool disposing)
+    {
+        foreach (var s in Values.Where(v => v != null))
+        {
+            s.Dispose();
+        }
+    }
+}

+ 5 - 5
Masuit.Tools.Abstractions/Systems/DisposeableDictionary.cs → Masuit.Tools.Abstractions/Systems/DisposableDictionary.cs

@@ -9,14 +9,14 @@ namespace Masuit.Tools.Systems;
 /// </summary>
 /// <typeparam name="TKey"></typeparam>
 /// <typeparam name="TValue"></typeparam>
-public class DisposeableDictionary<TKey, TValue> : NullableDictionary<TKey, TValue>, IDisposable where TValue : IDisposable
+public class DisposableDictionary<TKey, TValue> : NullableDictionary<TKey, TValue>, IDisposable where TValue : IDisposable
 {
     private bool _isDisposed;
 
     /// <summary>
     /// 终结器
     /// </summary>
-    ~DisposeableDictionary()
+    ~DisposableDictionary()
     {
         Dispose(false);
     }
@@ -36,15 +36,15 @@ public class DisposeableDictionary<TKey, TValue> : NullableDictionary<TKey, TVal
         GC.SuppressFinalize(this);
     }
 
-    public DisposeableDictionary() : base()
+    public DisposableDictionary() : base()
     {
     }
 
-    public DisposeableDictionary(int capacity) : base(capacity)
+    public DisposableDictionary(int capacity) : base(capacity)
     {
     }
 
-    public DisposeableDictionary(IDictionary<NullObject<TKey>, TValue> dictionary) : base(dictionary)
+    public DisposableDictionary(IDictionary<NullObject<TKey>, TValue> dictionary) : base(dictionary)
     {
     }
 

+ 6 - 0
Masuit.Tools.Abstractions/Systems/NullableConcurrentDictionary.cs

@@ -30,6 +30,12 @@ public class NullableConcurrentDictionary<TKey, TValue> : ConcurrentDictionary<N
         set => base[key] = value;
     }
 
+    public virtual TValue this[TKey key]
+    {
+        get => TryGetValue(key, out var value) ? value : FallbackValue;
+        set => base[key] = value;
+    }
+
     /// <summary>
     /// 隐式转换
     /// </summary>

+ 10 - 0
Masuit.Tools.Abstractions/Systems/NullableDictionary.cs

@@ -46,6 +46,16 @@ public class NullableDictionary<TKey, TValue> : Dictionary<NullObject<TKey>, TVa
         set => base[key] = value;
     }
 
+    /// <summary>
+    ///
+    /// </summary>
+    /// <param name="key"></param>
+    public virtual TValue this[TKey key]
+    {
+        get => TryGetValue(key, out var value) ? value : FallbackValue;
+        set => base[key] = value;
+    }
+
     /// <summary>
     /// 隐式转换
     /// </summary>

+ 1 - 1
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -18,7 +18,7 @@
         <LangVersion>latest</LangVersion>
         <RepositoryType>Github</RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-        <Version>1.0.6.2</Version>
+        <Version>1.0.6.3</Version>
         <FileVersion>1.0</FileVersion>
         <Company>masuit.com</Company>
         <AssemblyVersion>1.0</AssemblyVersion>

+ 4 - 3
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -18,7 +18,7 @@ github:https://github.com/ldqk/Masuit.Tools
         <UserSecretsId>830c282f-f7c1-42be-8651-4cd06ac8e73f</UserSecretsId>
         <RepositoryType>Github</RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-        <Version>2.4.9.2</Version>
+        <Version>2.4.9.3</Version>
         <FileVersion>2.4.5.6</FileVersion>
         <Company>masuit.com</Company>
         <AssemblyVersion>2.4.5.6</AssemblyVersion>
@@ -31,11 +31,11 @@ github:https://github.com/ldqk/Masuit.Tools
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="DnsClient" Version="1.6.0" />
+        <PackageReference Include="DnsClient" Version="1.6.1" />
         <PackageReference Include="HtmlSanitizer" Version="7.1.512" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
         <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
-        <PackageReference Include="SharpCompress" Version="0.31.0" />
+        <PackageReference Include="SharpCompress" Version="0.32.0" />
     </ItemGroup>
 
     <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
@@ -95,6 +95,7 @@ github:https://github.com/ldqk/Masuit.Tools
       <Compile Remove="..\Masuit.Tools.Abstractions\Models\Pois.cs" />
       <Compile Remove="..\Masuit.Tools.Abstractions\Models\TaobaoIP.cs" />
       <Compile Remove="..\Masuit.Tools.Abstractions\Reflection\ClassHelper.cs" />
+      <Compile Remove="..\Masuit.Tools.Abstractions\Systems\DisposeableDictionary.cs" />
     </ItemGroup>
 
     <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

+ 1 - 1
Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

@@ -29,7 +29,7 @@
         <DocumentationFile>.\Masuit.Tools.Excel.xml</DocumentationFile>
     </PropertyGroup>
     <ItemGroup>
-        <PackageReference Include="EPPlus" Version="6.0.4" />
+        <PackageReference Include="EPPlus" Version="6.0.5" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
         <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
         <PackageReference Include="SixLabors.ImageSharp" Version="2.1.2" />

+ 3 - 48
Masuit.Tools.Net45/Masuit.Tools.Net45.csproj

@@ -259,53 +259,8 @@
     <Compile Include="..\Masuit.Tools.Abstractions\Strings\Template.cs">
       <Link>Strings\Template.cs</Link>
     </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\CompositeContractResolver.cs">
-      <Link>Systems\CompositeContractResolver.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\ConcurrentLimitedQueue.cs">
-      <Link>Systems\ConcurrentLimitedQueue.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\DeserializeOnlyContractResolver.cs">
-      <Link>Systems\DeserializeOnlyContractResolver.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\DeserializeOnlyJsonPropertyAttribute.cs">
-      <Link>Systems\DeserializeOnlyJsonPropertyAttribute.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\Disposable.cs">
-      <Link>Systems\Disposable.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\EnumExt.cs">
-      <Link>Systems\EnumExt.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\FallbackJsonProperty.cs">
-      <Link>Systems\FallbackJsonProperty.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\FallbackJsonPropertyResolver.cs">
-      <Link>Systems\FallbackJsonPropertyResolver.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\HiPerfTimer.cs">
-      <Link>Systems\HiPerfTimer.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\LimitedQueue.cs">
-      <Link>Systems\LimitedQueue.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\NullableConcurrentDictionary.cs">
-      <Link>Systems\NullableConcurrentDictionary.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\NullableDictionary.cs">
-      <Link>Systems\NullableDictionary.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\NullObject.cs">
-      <Link>Systems\NullObject.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\SerializeIgnoreAttribute.cs">
-      <Link>Systems\SerializeIgnoreAttribute.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\SnowFlake.cs">
-      <Link>Systems\SnowFlake.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\StopwatchHelper.cs">
-      <Link>Systems\StopwatchHelper.cs</Link>
+    <Compile Include="..\Masuit.Tools.Abstractions\Systems\*.*">
+      <Link>Systems\%(RecursiveDir)%(FileName)%(Extension)</Link>
     </Compile>
     <Compile Include="..\Masuit.Tools.Abstractions\Validator\ComplexPassword.cs">
       <Link>Validator\ComplexPassword.cs</Link>
@@ -386,7 +341,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="DnsClient">
-      <Version>1.6.0</Version>
+      <Version>1.6.1</Version>
     </PackageReference>
     <PackageReference Include="Microsoft.AspNet.Mvc">
       <Version>5.2.9</Version>

+ 1 - 6
Masuit.Tools.Net45/package.nuspec

@@ -1,21 +1,16 @@
 <?xml version="1.0"?>
 <package>
   <metadata>
-    <!--*-->
     <id>Masuit.Tools.Net45</id>
-    <!--*-->
-    <version>2.4.9.2</version>
+    <version>2.4.9.3</version>
     <title>Masuit.Tools</title>
-    <!--*-->
     <authors>懒得勤快</authors>
     <owners>masuit.com</owners>
     <licenseUrl>https://github.com/ldqk/Masuit.Tools/blob/master/LICENSE</licenseUrl>
     <projectUrl>https://github.com/ldqk/Masuit.Tools</projectUrl>
     <!--<iconUrl></iconUrl>-->
     <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <!--*-->
     <description>Masuit.Tools的.NET Framework 4.5专用版本,相比4.6.1及.NET Core的版本,阉割了HTML、文件压缩、ASP.NET扩展、硬件监测、Session扩展等功能。</description>
-    <!--*-->
     <releaseNotes>如有问题请联系作者QQ:3444764617,或者到项目的github反馈问题,详细的API文档在github上:https://github.com/ldqk/Masuit.Tools</releaseNotes>
     <copyright>Copyright ©  懒得勤快</copyright>
     <tags>Masuit.Tools,工具库,Utility,Crypt,Extensions</tags>

+ 2 - 2
Masuit.Tools/Files/SevenZipCompressor.cs

@@ -47,7 +47,7 @@ namespace Masuit.Tools.Files
         /// <param name="archiveType"></param>
         /// <param name="disposeAllStreams">是否需要释放所有流</param>
         /// <returns>文件流</returns>
-        public static MemoryStream ZipStream(DisposeableDictionary<string, Stream> streams, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
+        public static MemoryStream ZipStream(DisposableDictionary<string, Stream> streams, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
         {
             using var archive = ArchiveFactory.Create(archiveType);
             foreach (var pair in streams)
@@ -98,7 +98,7 @@ namespace Masuit.Tools.Files
         /// <param name="zipFile">压缩到...</param>
         /// <param name="archiveType"></param>
         /// <param name="disposeAllStreams">是否需要释放所有流</param>
-        public static void Zip(DisposeableDictionary<string, Stream> streams, string zipFile, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
+        public static void Zip(DisposableDictionary<string, Stream> streams, string zipFile, ArchiveType archiveType = ArchiveType.Zip, bool disposeAllStreams = false)
         {
             using var archive = ArchiveFactory.Create(archiveType);
             foreach (var pair in streams)

+ 2 - 29
Masuit.Tools/Masuit.Tools.csproj

@@ -112,33 +112,6 @@
     <Compile Include="..\Masuit.Tools.Abstractions\Systems\*.*">
       <Link>Systems\%(RecursiveDir)%(FileName)%(Extension)</Link>
     </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\CompositeContractResolver.cs">
-      <Link>Systems\CompositeContractResolver.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\DeserializeOnlyJsonPropertyAttribute.cs">
-      <Link>Systems\DeserializeOnlyJsonPropertyAttribute.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\DisposeableDictionary.cs">
-      <Link>Systems\DisposeableDictionary.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\FallbackJsonProperty.cs">
-      <Link>Systems\FallbackJsonProperty.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\FallbackJsonPropertyResolver.cs">
-      <Link>Systems\FallbackJsonPropertyResolver.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\NullableConcurrentDictionary.cs">
-      <Link>Systems\NullableConcurrentDictionary.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\NullableDictionary.cs">
-      <Link>Systems\NullableDictionary.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\NullObject.cs">
-      <Link>Systems\NullObject.cs</Link>
-    </Compile>
-    <Compile Include="..\Masuit.Tools.Abstractions\Systems\SerializeIgnoreAttribute.cs">
-      <Link>Systems\SerializeIgnoreAttribute.cs</Link>
-    </Compile>
     <Compile Include="..\Masuit.Tools.Abstractions\Validator\*.*">
       <Link>Validator\%(RecursiveDir)%(FileName)%(Extension)</Link>
     </Compile>
@@ -190,7 +163,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="DnsClient">
-      <Version>1.6.0</Version>
+      <Version>1.6.1</Version>
     </PackageReference>
     <PackageReference Include="HtmlSanitizer">
       <Version>7.1.512</Version>
@@ -202,7 +175,7 @@
       <Version>13.0.1</Version>
     </PackageReference>
     <PackageReference Include="SharpCompress">
-      <Version>0.31.0</Version>
+      <Version>0.32.0</Version>
     </PackageReference>
     <PackageReference Include="StackExchange.Redis">
       <Version>2.5.61</Version>

+ 1 - 7
Masuit.Tools/package.nuspec

@@ -1,25 +1,19 @@
 <?xml version="1.0"?>
 <package>
   <metadata>
-    <!--*-->
     <id>Masuit.Tools.Net</id>
-    <!--*-->
-    <version>2.4.9.2</version>
+    <version>2.4.9.3</version>
     <title>Masuit.Tools</title>
-    <!--*-->
     <authors>懒得勤快</authors>
     <owners>masuit.com</owners>
     <licenseUrl>https://github.com/ldqk/Masuit.Tools/blob/master/LICENSE</licenseUrl>
     <projectUrl>https://github.com/ldqk/Masuit.Tools</projectUrl>
-    <!--<iconUrl></iconUrl>-->
     <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <!--*-->
     <description>包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。
 官网教程:https://ldqk.org/55
 
 
 github:https://github.com/ldqk/Masuit.Tools</description>
-    <!--*-->
     <releaseNotes>如有问题请联系作者QQ:3444764617,或者到项目的github反馈问题,详细的API文档在github上:https://github.com/ldqk/Masuit.Tools</releaseNotes>
     <copyright>Copyright ©  懒得勤快</copyright>
     <tags>Masuit.Tools,工具库,Utility,Crypt,Extensions</tags>