From 3095dc783e518d0c1f8a022b489920fda1d39e69 Mon Sep 17 00:00:00 2001 From: nsnail Date: Thu, 15 Dec 2022 14:12:34 +0800 Subject: [PATCH 1/3] --- .editorconfig | 28 ++- ...-files-to-sln.csx => AddMetaFilesToSln.csx | 0 ...eanup-on-save.csx => CodeCleanupOnSave.csx | 0 CodeQuality.props | 17 ++ Directory.Build.props | 8 +- ImageOptimize.csx | 45 ++++ NSExt.sln | 11 +- dot.sln.DotSettings => NSExt.sln.DotSettings | 55 +++-- StyleCopAnalyzers.ruleset | 221 ++++++++++++++++++ build.cake | 20 +- dotnet-tools.json | 1 - git-clean.ps1 => git-clean.cmd | 0 push2nuget.ps1 | 6 +- src/Extensions/ByteExtensions.cs | 20 +- src/Extensions/CharExtensions.cs | 7 +- src/Extensions/DateTimeExtensions.cs | 66 +++--- src/Extensions/DbCommandExtensions.cs | 34 ++- src/Extensions/DecimalExtensions.cs | 3 + src/Extensions/EnumExtensions.cs | 5 +- src/Extensions/EnumerableExtensions.cs | 6 +- src/Extensions/GenericExtensions.cs | 28 +-- src/Extensions/IntExtensions.cs | 13 +- .../JsonSerializerOptionsExtensions.cs | 8 +- src/Extensions/LoggerExtensions.cs | 71 ++++-- src/Extensions/LongExtensions.cs | 12 +- src/Extensions/ObjectExtensions.cs | 3 + src/Extensions/StreamExtensions.cs | 15 +- src/Extensions/StringExtensions.cs | 163 +++++-------- src/Extensions/TypeExtensions.cs | 6 +- src/Extensions/UriExtensions.cs | 5 +- src/GlobalUsings.cs | 6 +- src/NSExt.csproj | 11 +- stylecop.json | 9 + 33 files changed, 644 insertions(+), 259 deletions(-) rename add-meta-files-to-sln.csx => AddMetaFilesToSln.csx (100%) rename code-cleanup-on-save.csx => CodeCleanupOnSave.csx (100%) create mode 100644 CodeQuality.props create mode 100644 ImageOptimize.csx rename dot.sln.DotSettings => NSExt.sln.DotSettings (68%) create mode 100644 StyleCopAnalyzers.ruleset rename git-clean.ps1 => git-clean.cmd (100%) create mode 100644 stylecop.json diff --git a/.editorconfig b/.editorconfig index 8c3845c..2127d46 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,12 +1,28 @@ root = true [*] -indent_style = space -indent_size = 4 -end_of_line = lf charset = utf-8 +end_of_line = lf +ij_xml_attribute_wrap = off +ij_xml_text_wrap = off +indent_size = 4 +indent_style = space +insert_final_newline = false trim_trailing_whitespace = true +[*.cs] +dotnet_analyzer_diagnostic.severity = warning +dotnet_diagnostic.CA1707.severity = none +dotnet_diagnostic.CA1720.severity = none +dotnet_diagnostic.CA5350.severity = none +dotnet_diagnostic.CA5351.severity = none +dotnet_diagnostic.IDE0008.severity = none +dotnet_diagnostic.IDE0017.severity = none +dotnet_diagnostic.IDE0048.severity = none +dotnet_diagnostic.IDE0055.severity = none +dotnet_diagnostic.IDE0058.severity = none +dotnet_diagnostic.IDE0160.severity = none + # ReSharper properties resharper_align_linq_query = true @@ -23,23 +39,27 @@ resharper_align_multline_type_parameter_constrains = true resharper_align_multline_type_parameter_list = true resharper_align_tuple_components = true resharper_allow_comment_after_lbrace = true +resharper_blank_lines_before_single_line_comment = 1 resharper_csharp_empty_block_style = together_same_line resharper_csharp_outdent_commas = true +resharper_csharp_place_type_constraints_on_same_line = false resharper_csharp_stick_comment = false resharper_csharp_wrap_before_comma = true -resharper_indent_nested_foreach_stmt = true resharper_indent_nested_for_stmt = true +resharper_indent_nested_foreach_stmt = true resharper_indent_nested_while_stmt = true resharper_indent_preprocessor_if = usual_indent resharper_indent_preprocessor_other = usual_indent resharper_int_align = true resharper_keep_existing_arrangement = false resharper_place_linq_into_on_new_line = false +resharper_place_simple_embedded_statement_on_same_line = false resharper_place_simple_switch_expression_on_single_line = true resharper_wrap_before_eq = true resharper_wrap_chained_method_calls = chop_if_long resharper_wrap_switch_expression = chop_if_long + # Microsoft .NET properties csharp_indent_braces = false csharp_new_line_before_open_brace = local_functions, methods, types \ No newline at end of file diff --git a/add-meta-files-to-sln.csx b/AddMetaFilesToSln.csx similarity index 100% rename from add-meta-files-to-sln.csx rename to AddMetaFilesToSln.csx diff --git a/code-cleanup-on-save.csx b/CodeCleanupOnSave.csx similarity index 100% rename from code-cleanup-on-save.csx rename to CodeCleanupOnSave.csx diff --git a/CodeQuality.props b/CodeQuality.props new file mode 100644 index 0000000..df0775d --- /dev/null +++ b/CodeQuality.props @@ -0,0 +1,17 @@ + + + ../StyleCopAnalyzers.ruleset + true + true + true + true + true + true + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index f6fcf75..11cee10 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,9 +1,11 @@ enable - ../build/$(MSBuildProjectName)/bin - ../build/$(MSBuildProjectName)/obj - $(BaseIntermediateOutputPath) + ../dist + ../dist + $(BaseOutputPath)/$(MSBuildProjectName)/bin + $(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj + $(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj nsnail NSExt © 2006-2022 nsnail diff --git a/ImageOptimize.csx b/ImageOptimize.csx new file mode 100644 index 0000000..8e6aca7 --- /dev/null +++ b/ImageOptimize.csx @@ -0,0 +1,45 @@ +/* + for %%i in (*.png) do pngquant %%i --force --output %%i --skip-if-larger + for %%i in (*.jpg) do jpegtran -copy none -optimize -perfect %%i %%i + * + */ + + var files = Directory.EnumerateFiles(".", "*.png" + , new EnumerationOptions { + RecurseSubdirectories = true + , AttributesToSkip = FileAttributes.ReparsePoint + , IgnoreInaccessible = true + }) + .ToArray(); + + + Parallel.ForEach(files, file => { + var startInfo = new ProcessStartInfo { + FileName = "pngquant" + , Arguments + = $"\"{file}\" --force --output \"{file}\" --skip-if-larger" + }; + using var p = Process.Start(startInfo); + p.WaitForExit(); + Console.WriteLine($"{file}: {p.ExitCode}"); + }); + + files = new[] { "*.jpg", "*.jpeg" } + .SelectMany(x => Directory.EnumerateFiles( + ".", x + , new EnumerationOptions { + RecurseSubdirectories = true + , AttributesToSkip = FileAttributes.ReparsePoint + , IgnoreInaccessible = true + })) + .ToArray(); + + Parallel.ForEach(files, file => { + var startInfo = new ProcessStartInfo { + FileName = "jpegtran" + , Arguments = $"-copy none -optimize -perfect \"{file}\" \"{file}\"" + }; + using var p = Process.Start(startInfo); + p.WaitForExit(); + Console.WriteLine($"{file}: {p.ExitCode}"); + }); \ No newline at end of file diff --git a/NSExt.sln b/NSExt.sln index 4e16c72..d4e6c45 100644 --- a/NSExt.sln +++ b/NSExt.sln @@ -11,17 +11,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-F .gitattributes = .gitattributes .gitignore = .gitignore .tgitconfig = .tgitconfig - add-meta-files-to-sln.csx = add-meta-files-to-sln.csx - code-cleanup-on-save.csx = code-cleanup-on-save.csx + AddMetaFilesToSln.csx = AddMetaFilesToSln.csx + build.cake = build.cake code-format.cmd = code-format.cmd + CodeCleanupOnSave.csx = CodeCleanupOnSave.csx + CodeQuality.props = CodeQuality.props Directory.Build.props = Directory.Build.props dot.sln.DotSettings = dot.sln.DotSettings dotnet-tools.json = dotnet-tools.json - git-clean.ps1 = git-clean.ps1 + git-clean.cmd = git-clean.cmd global.json = global.json + ImageOptimize.csx = ImageOptimize.csx LICENSE = LICENSE push2nuget.ps1 = push2nuget.ps1 README.md = README.md + stylecop.json = stylecop.json + StyleCopAnalyzers.ruleset = StyleCopAnalyzers.ruleset EndProjectSection EndProject Global diff --git a/dot.sln.DotSettings b/NSExt.sln.DotSettings similarity index 68% rename from dot.sln.DotSettings rename to NSExt.sln.DotSettings index 205c3ab..aebd72b 100644 --- a/dot.sln.DotSettings +++ b/NSExt.sln.DotSettings @@ -1,6 +1,18 @@ - + + False + 1 + 1 + OFF + HINT + Required + Required + Required + Required + <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <?xml version="1.0" encoding="utf-16"?> <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> <TypePattern> @@ -8,43 +20,38 @@ <Entry.SortBy> <Kind> <Kind.Order> - <DeclarationKind>Interface</DeclarationKind> - <DeclarationKind>Class</DeclarationKind> - <DeclarationKind>Record</DeclarationKind> - <DeclarationKind>Enum</DeclarationKind> - <DeclarationKind>Struct</DeclarationKind> - <DeclarationKind>Delegate</DeclarationKind> - <DeclarationKind>Event</DeclarationKind> <DeclarationKind>Constant</DeclarationKind> <DeclarationKind>Field</DeclarationKind> - <DeclarationKind>Property</DeclarationKind> <DeclarationKind>Constructor</DeclarationKind> <DeclarationKind>Destructor</DeclarationKind> + <DeclarationKind>Delegate</DeclarationKind> + <DeclarationKind>Event</DeclarationKind> + <DeclarationKind>Enum</DeclarationKind> + <DeclarationKind>Interface</DeclarationKind> + <DeclarationKind>Property</DeclarationKind> <DeclarationKind>Indexer</DeclarationKind> <DeclarationKind>Method</DeclarationKind> + <DeclarationKind>Struct</DeclarationKind> + <DeclarationKind>Record</DeclarationKind> + <DeclarationKind>Class</DeclarationKind> </Kind.Order> </Kind> <Access> <Access.Order> - <AccessModifier>Private</AccessModifier> - <AccessModifier>PrivateProtected</AccessModifier> - <AccessModifier>Protected</AccessModifier> - <AccessModifier>ProtectedInternal</AccessModifier> - <AccessModifier>Internal</AccessModifier> <AccessModifier>Public</AccessModifier> + <AccessModifier>Internal</AccessModifier> + <AccessModifier>ProtectedInternal</AccessModifier> + <AccessModifier>Protected</AccessModifier> + <AccessModifier>PrivateProtected</AccessModifier> + <AccessModifier>Private</AccessModifier> </Access.Order> </Access> + <Static /> + <Readonly /> <Name /> </Entry.SortBy> </Entry> </TypePattern> </Patterns> - <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> - <Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /> - <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - False - HINT + \ No newline at end of file diff --git a/StyleCopAnalyzers.ruleset b/StyleCopAnalyzers.ruleset new file mode 100644 index 0000000..f76edfe --- /dev/null +++ b/StyleCopAnalyzers.ruleset @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.cake b/build.cake index ca99a64..1c37c0b 100644 --- a/build.cake +++ b/build.cake @@ -1,6 +1,6 @@ var target = Argument("target", "Default"); var configuration = Argument("configuration", "Release"); -var pkgOutPath = $"./build/NSExt/pkg/{configuration}"; +var pkgOutPath = $"./dist/NSExt/pkg/{configuration}"; //////////////////////////////////////////////////////////////// // Tasks @@ -13,7 +13,7 @@ Task("Clean") Task("Build") .IsDependentOn("Clean") - .Does(context => + .Does(context => { DotNetBuild("./NSExt.sln", new DotNetBuildSettings { Configuration = configuration, @@ -26,7 +26,7 @@ Task("Build") Task("Test") .IsDependentOn("Build") - .Does(context => + .Does(context => { DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings { Configuration = configuration, @@ -49,7 +49,7 @@ Task("Test") Task("Package") .IsDependentOn("Build") - .Does(context => + .Does(context => { context.DotNetPack("./NSExt.sln", new DotNetPackSettings { Configuration = configuration, @@ -64,7 +64,7 @@ Task("Package") Task("Publish-GitHub") .WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions") .IsDependentOn("Package") - .Does(context => + .Does(context => { var apiKey = Argument("github-key", null); if(string.IsNullOrWhiteSpace(apiKey)) { @@ -73,10 +73,10 @@ Task("Publish-GitHub") // Publish to GitHub Packages var exitCode = 0; - foreach(var file in context.GetFiles("./.artifacts/*.nupkg")) + foreach(var file in context.GetFiles("./.artifacts/*.nupkg")) { context.Information("Publishing {0}...", file.GetFilename().FullPath); - exitCode += StartProcess("dotnet", + exitCode += StartProcess("dotnet", new ProcessSettings { Arguments = new ProcessArgumentBuilder() .Append("gpr") @@ -87,7 +87,7 @@ Task("Publish-GitHub") ); } - if(exitCode != 0) + if(exitCode != 0) { throw new CakeException("Could not push GitHub packages."); } @@ -96,7 +96,7 @@ Task("Publish-GitHub") Task("Publish-NuGet") // .WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions") .IsDependentOn("Package") - .Does(context => + .Does(context => { var apiKey = Argument("nuget-key", null); if(string.IsNullOrWhiteSpace(apiKey)) { @@ -104,7 +104,7 @@ Task("Publish-NuGet") } // Publish to GitHub Packages - foreach(var file in context.GetFiles($"{pkgOutPath}/*.*nupkg")) + foreach(var file in context.GetFiles($"{pkgOutPath}/*.*nupkg")) { context.Information("Publishing {0}...", file.GetFilename().FullPath); DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings diff --git a/dotnet-tools.json b/dotnet-tools.json index 55de44c..1158904 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -2,6 +2,5 @@ "version": 1, "isRoot": true, "tools": { - } } \ No newline at end of file diff --git a/git-clean.ps1 b/git-clean.cmd similarity index 100% rename from git-clean.ps1 rename to git-clean.cmd diff --git a/push2nuget.ps1 b/push2nuget.ps1 index 13df55a..24d0798 100644 --- a/push2nuget.ps1 +++ b/push2nuget.ps1 @@ -1,5 +1,5 @@ Param( - # Nuget APIKey +# Nuget APIKey [string] $apikey ) @@ -12,13 +12,13 @@ if ($apikey -eq $null -or $apikey -eq "") rm -r ./build/nupkgs dotnet build -c Release $files = Get-ChildItem -Path ./build/nupkgs/ -Filter *.nupkg -foreach($file in $files) +foreach ($file in $files) { dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json nuget add $file.fullName -source d:\nuget-pkg } $files = Get-ChildItem -Path ./build/nupkgs/ -Filter *.snupkg -foreach($file in $files) +foreach ($file in $files) { dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json nuget add $file.fullName -source d:\nuget-pkg diff --git a/src/Extensions/ByteExtensions.cs b/src/Extensions/ByteExtensions.cs index b443098..46cb98c 100644 --- a/src/Extensions/ByteExtensions.cs +++ b/src/Extensions/ByteExtensions.cs @@ -1,5 +1,8 @@ namespace NSExt.Extensions; +/// +/// ByteExtensions +/// public static class ByteExtensions { /// @@ -12,7 +15,6 @@ public static class ByteExtensions return Convert.ToBase64String(me); } - /// /// 将字节数组解码成字符串 /// @@ -24,7 +26,6 @@ public static class ByteExtensions return e.GetString(me); } - /// /// 将字节数组解码成字符串 /// @@ -38,15 +39,20 @@ public static class ByteExtensions /// /// 将字节数组转换成16进制字符串 /// - /// + /// me /// 是否大写 /// 字节间分隔符 - /// public static string String(this byte[] me, bool upperCase = true, string splitShar = null) { - var ret = BitConverter.ToString(me); - if (!upperCase) ret = ret.ToLower(); - if (splitShar != "-") ret = ret.Replace("-", splitShar ?? string.Empty); + var ret = BitConverter.ToString(me); + if (!upperCase) { + ret = ret.ToLower(CultureInfo.InvariantCulture); + } + + if (splitShar != "-") { + ret = ret.Replace("-", splitShar ?? string.Empty); + } + return ret; } } \ No newline at end of file diff --git a/src/Extensions/CharExtensions.cs b/src/Extensions/CharExtensions.cs index 319cf91..3d5438a 100644 --- a/src/Extensions/CharExtensions.cs +++ b/src/Extensions/CharExtensions.cs @@ -1,12 +1,13 @@ namespace NSExt.Extensions; +/// +/// CharExtensions +/// public static class CharExtensions { /// /// 是否数字或大小写字母 /// - /// - /// public static bool IsAsciiLetterOrDigit(this char me) { return (((uint)me - 'A') & ~0x20) < 26 || (uint)me - '0' < 10; @@ -15,8 +16,6 @@ public static class CharExtensions /// /// 是否base64字符 /// - /// - /// public static bool IsBase64Character(this char me) { return IsAsciiLetterOrDigit(me) || me is '+' or '/' or '='; diff --git a/src/Extensions/DateTimeExtensions.cs b/src/Extensions/DateTimeExtensions.cs index 2e904b2..ac8cb43 100644 --- a/src/Extensions/DateTimeExtensions.cs +++ b/src/Extensions/DateTimeExtensions.cs @@ -1,27 +1,28 @@ +// ReSharper disable InconsistentNaming // ReSharper disable UnusedMember.Global +#pragma warning disable SA1300 +#pragma warning disable IDE1006 namespace NSExt.Extensions; +/// +/// DateTimeExtensions +/// public static class DateTimeExtensions { /// - /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串,如2秒以前,3天以前 + /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前 /// /// 时间对象 /// 字符串 public static string TimeAgo(this DateTime me) { var ts = DateTime.Now - me; - if (ts.Days > 0) return ts.Days + "天前"; - - if (ts.Hours > 0) return ts.Hours + "小时前"; - - if (ts.Minutes > 0) return ts.Minutes + "分钟前"; - - return ts.Seconds + "秒前"; + return ts.Days > 0 ? ts.Days + "天前" : + ts.Hours > 0 ? ts.Hours + "小时前" : + ts.Minutes > 0 ? ts.Minutes + "分钟前" : ts.Seconds + "秒前"; } - /// /// 指定时间的世界协调时的unix时间戳形式 /// @@ -35,55 +36,64 @@ public static class DateTimeExtensions /// /// 指定时间的世界协调时的unix时间戳形式(毫秒) /// - /// - /// public static long TimeUnixUtcMs(this DateTime me) { return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000; } - - // ReSharper disable once InconsistentNaming + /// + /// yyyy_MM + /// public static string yyyy_MM(this DateTime me) { - return me.ToString("yyyy-MM"); + return me.ToString("yyyy-MM", CultureInfo.InvariantCulture); } - // ReSharper disable once InconsistentNaming + /// + /// yyyy_MM_dd + /// public static string yyyy_MM_dd(this DateTime me) { - return me.ToString("yyyy-MM-dd"); + return me.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); } - // ReSharper disable once InconsistentNaming + /// + /// yyyy_MM_dd_HH_mm + /// public static string yyyy_MM_dd_HH_mm(this DateTime me) { - return me.ToString("yyyy-MM-dd HH:mm"); + return me.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); } - - // ReSharper disable once InconsistentNaming + /// + /// yyyy_MM_dd_HH_mm_ss + /// public static string yyyy_MM_dd_HH_mm_ss(this DateTime me) { - return me.ToString("yyyy-MM-dd HH:mm:ss"); + return me.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); } - // ReSharper disable once InconsistentNaming + /// + /// yyyy_MM_dd_HH_mm_ss_fff + /// public static string yyyy_MM_dd_HH_mm_ss_fff(this DateTime me) { - return me.ToString("yyyy-MM-dd HH:mm:ss.fff"); + return me.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); } - - // ReSharper disable once InconsistentNaming + /// + /// yyyyMM + /// public static string yyyyMM(this DateTime me) { - return me.ToString("yyyyMM"); + return me.ToString("yyyyMM", CultureInfo.InvariantCulture); } - // ReSharper disable once InconsistentNaming + /// + /// yyyyMMdd + /// public static string yyyyMMdd(this DateTime me) { - return me.ToString("yyyyMMdd"); + return me.ToString("yyyyMMdd", CultureInfo.InvariantCulture); } } \ No newline at end of file diff --git a/src/Extensions/DbCommandExtensions.cs b/src/Extensions/DbCommandExtensions.cs index caaf214..d1a4e75 100644 --- a/src/Extensions/DbCommandExtensions.cs +++ b/src/Extensions/DbCommandExtensions.cs @@ -1,28 +1,46 @@ namespace NSExt.Extensions; +/// +/// DbCommandExtensions +/// public static class DbCommandExtensions { /// /// 格式化参数拼接成完整的SQL语句 /// - /// public static string ParameterFormat(this DbCommand me) { //var aa = pars.ToDictionary(it => it.ParameterName, it => it.Value); var sql = me.CommandText; //应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10 - for (var i = me.Parameters.Count - 1; i >= 0; i--) + for (var i = me.Parameters.Count - 1; i >= 0; i--) { sql = me.Parameters[i].DbType switch { DbType.String or DbType.DateTime or DbType.Date or DbType.Time or DbType.DateTime2 or DbType.DateTimeOffset or DbType.Guid or DbType.VarNumeric or DbType.AnsiStringFixedLength - or DbType.AnsiString - or DbType.StringFixedLength => - sql.Replace(me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'") - , DbType.Boolean => sql.Replace(me.Parameters[i].ParameterName - , Convert.ToBoolean(me.Parameters[i].Value) ? "1" : "0") - , _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString()) + or DbType.AnsiString or DbType.StringFixedLength => sql.Replace( // + me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'") + , DbType.Boolean => sql.Replace( // + me.Parameters[i].ParameterName + , Convert.ToBoolean(me.Parameters[i].Value, CultureInfo.InvariantCulture) ? "1" : "0") + , DbType.Binary => throw new NotImplementedException() + , DbType.Byte => throw new NotImplementedException() + , DbType.Currency => throw new NotImplementedException() + , DbType.Decimal => throw new NotImplementedException() + , DbType.Double => throw new NotImplementedException() + , DbType.Int16 => throw new NotImplementedException() + , DbType.Int32 => throw new NotImplementedException() + , DbType.Int64 => throw new NotImplementedException() + , DbType.Object => throw new NotImplementedException() + , DbType.SByte => throw new NotImplementedException() + , DbType.Single => throw new NotImplementedException() + , DbType.UInt16 => throw new NotImplementedException() + , DbType.UInt32 => throw new NotImplementedException() + , DbType.UInt64 => throw new NotImplementedException() + , DbType.Xml => throw new NotImplementedException() + , _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString()) }; + } return sql; } diff --git a/src/Extensions/DecimalExtensions.cs b/src/Extensions/DecimalExtensions.cs index 3695204..6dfd32a 100644 --- a/src/Extensions/DecimalExtensions.cs +++ b/src/Extensions/DecimalExtensions.cs @@ -1,5 +1,8 @@ namespace NSExt.Extensions; +/// +/// DecimalExtensions +/// public static class DecimalExtensions { /// diff --git a/src/Extensions/EnumExtensions.cs b/src/Extensions/EnumExtensions.cs index a7e5827..80ae7bd 100644 --- a/src/Extensions/EnumExtensions.cs +++ b/src/Extensions/EnumExtensions.cs @@ -1,5 +1,8 @@ namespace NSExt.Extensions; +/// +/// EnumExtensions +/// public static class EnumExtensions { /// @@ -12,6 +15,6 @@ public static class EnumExtensions var t = e.GetType(); var fi = t.GetField(Enum.GetName(t, e)!); var attrs = (DescriptionAttribute[])fi!.GetCustomAttributes(typeof(DescriptionAttribute), false); - return (attrs.Length != 0 ? attrs[0].Description : Enum.GetName(t, e)) ?? ""; + return (attrs.Length != 0 ? attrs[0].Description : Enum.GetName(t, e)) ?? string.Empty; } } \ No newline at end of file diff --git a/src/Extensions/EnumerableExtensions.cs b/src/Extensions/EnumerableExtensions.cs index 067f057..ebebe01 100644 --- a/src/Extensions/EnumerableExtensions.cs +++ b/src/Extensions/EnumerableExtensions.cs @@ -1,13 +1,13 @@ namespace NSExt.Extensions; +/// +/// EnumerableExtensions +/// public static class EnumerableExtensions { /// /// 将列表转成分隔符分隔的字符串 /// - /// - /// - /// public static string Join(this IEnumerable me, string separator) { return string.Join(separator, me); diff --git a/src/Extensions/GenericExtensions.cs b/src/Extensions/GenericExtensions.cs index 1cf4cd2..62f4d6f 100644 --- a/src/Extensions/GenericExtensions.cs +++ b/src/Extensions/GenericExtensions.cs @@ -1,5 +1,8 @@ namespace NSExt.Extensions; +/// +/// GenericExtensions +/// public static class GenericExtensions { /// @@ -14,27 +17,24 @@ public static class GenericExtensions , bool isIncludeOrExclude = false) { foreach (var p in me.GetType().GetProperties()) { - if (!p.CanWrite) continue; - bool isSet; - if (isIncludeOrExclude) - isSet = propNameList?.Contains(p.Name) ?? false; - else - isSet = !propNameList?.Contains(p.Name) ?? true; + if (!p.CanWrite) { + continue; + } - if (isSet) p.SetValue(me, copyObj.GetType().GetProperty(p.Name)?.GetValue(copyObj, null), null); + var isSet = isIncludeOrExclude + ? propNameList?.Contains(p.Name) ?? false + : !propNameList?.Contains(p.Name) ?? true; + if (isSet) { + p.SetValue(me, copyObj.GetType().GetProperty(p.Name)?.GetValue(copyObj, null), null); + } } } - /// /// 判断是否与某对象相等 /// - /// - /// - /// - /// - /// - public static T Is(this T me, T compare, T ret) where T : struct + public static T Is(this T me, T compare, T ret) + where T : struct { return me.Equals(compare) ? ret : me; } diff --git a/src/Extensions/IntExtensions.cs b/src/Extensions/IntExtensions.cs index 5f80e42..cce825d 100644 --- a/src/Extensions/IntExtensions.cs +++ b/src/Extensions/IntExtensions.cs @@ -1,15 +1,15 @@ namespace NSExt.Extensions; +/// +/// IntExtensions +/// public static class IntExtensions { /// /// 判断枚举是否包含某个位 /// - /// - /// - /// - /// - public static bool HasFlag(this int me, T flag) where T : Enum + public static bool HasFlag(this int me, T flag) + where T : Enum { return ((long)me).HasFlag(flag); } @@ -18,7 +18,6 @@ public static class IntExtensions /// 生成随机数 /// /// 大于等于[0],小于[1] - /// public static int Rand(this int[] me) { return new Random(Guid.NewGuid().GetHashCode()).Next(me[0], me[1]); @@ -27,8 +26,6 @@ public static class IntExtensions /// /// 转换成ipv4 /// - /// - /// public static string ToIpV4(this int me) { return string.Join(".", BitConverter.GetBytes(me).Reverse()); diff --git a/src/Extensions/JsonSerializerOptionsExtensions.cs b/src/Extensions/JsonSerializerOptionsExtensions.cs index beae6e8..162c51e 100644 --- a/src/Extensions/JsonSerializerOptionsExtensions.cs +++ b/src/Extensions/JsonSerializerOptionsExtensions.cs @@ -4,9 +4,15 @@ using System.Text.Json.Serialization; namespace NSExt.Extensions; +/// +/// JsonSerializerOptionsExtensions +/// public static class JsonSerializerOptionsExtensions { - public static JsonSerializerOptions NewJsonSerializerOptions(this JsonSerializerOptions me) + /// + /// NewJsonSerializerOptions + /// + public static JsonSerializerOptions NewJsonSerializerOptions(this JsonSerializerOptions _) { return new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip diff --git a/src/Extensions/LoggerExtensions.cs b/src/Extensions/LoggerExtensions.cs index 4b9cd7f..317d2ee 100644 --- a/src/Extensions/LoggerExtensions.cs +++ b/src/Extensions/LoggerExtensions.cs @@ -2,48 +2,87 @@ namespace NSExt.Extensions; +/// +/// LoggerExtensions +/// public static class LoggerExtensions { - private static string CallerInfoMessage(object message, string callerName, string callerFilePath - , int callerLineNumber) - { - return - $"{message} "; - } + private const string _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER + = "{Message} "; + private static readonly Action _logDebug + = LoggerMessage.Define(LogLevel.Debug, default + , _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER); + + private static readonly Action _logError + = LoggerMessage.Define(LogLevel.Error, default + , _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER); + + private static readonly Action _logFatal + = LoggerMessage.Define(LogLevel.Critical, default + , _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER); + + private static readonly Action _logInfo + = LoggerMessage.Define(LogLevel.Information, default + , _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER); + + private static readonly Action _logWarn + = LoggerMessage.Define(LogLevel.Warning, default + , _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER); + + /// + /// Debug + /// public static void Debug(this ILogger me, object message, [CallerMemberName] string callerName = null , [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) { - me.LogDebug(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + _logDebug(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture) + , callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture) + , null); } - + /// + /// Error + /// public static void Error(this ILogger me, object message, [CallerMemberName] string callerName = null , [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) { - me.LogError(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + _logError(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture) + , callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture) + , null); } + /// + /// Fatal + /// public static void Fatal(this ILogger me, object message, Exception ex = null , [CallerMemberName] string callerName = null, [CallerFilePath] string callerFilePath = null , [CallerLineNumber] int callerLineNumber = 0) { - if (ex is null) - me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); - else - me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber), ex); + _logFatal(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture) + , callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture) + , ex); } - + /// + /// Info + /// public static void Info(this ILogger me, object message, [CallerMemberName] string callerName = null , [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) { - me.LogInformation(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + _logInfo(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture) + , callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture) + , null); } + /// + /// Warn + /// public static void Warn(this ILogger me, object message, [CallerMemberName] string callerName = null , [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) { - me.LogWarning(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + _logWarn(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture) + , callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture) + , null); } } \ No newline at end of file diff --git a/src/Extensions/LongExtensions.cs b/src/Extensions/LongExtensions.cs index e726f72..7c0c08b 100644 --- a/src/Extensions/LongExtensions.cs +++ b/src/Extensions/LongExtensions.cs @@ -1,15 +1,15 @@ namespace NSExt.Extensions; +/// +/// LongExtensions +/// public static class LongExtensions { /// /// 判断枚举是否包含某个位 /// - /// - /// - /// - /// - public static bool HasFlag(this long me, T flag) where T : Enum + public static bool HasFlag(this long me, T flag) + where T : Enum { var val = (long)(object)flag; return (me & val) == val; @@ -18,8 +18,6 @@ public static class LongExtensions /// /// 1970毫秒数转换成日期对象 /// - /// - /// public static DateTime Time(this long msFrom1970) { return new DateTime(1970, 1, 1).AddMilliseconds(msFrom1970).ToLocalTime(); diff --git a/src/Extensions/ObjectExtensions.cs b/src/Extensions/ObjectExtensions.cs index 007e792..783b2b8 100644 --- a/src/Extensions/ObjectExtensions.cs +++ b/src/Extensions/ObjectExtensions.cs @@ -2,6 +2,9 @@ using System.Text.Json; namespace NSExt.Extensions; +/// +/// ObjectExtensions +/// public static class ObjectExtensions { /// diff --git a/src/Extensions/StreamExtensions.cs b/src/Extensions/StreamExtensions.cs index 4f898ba..74fc642 100644 --- a/src/Extensions/StreamExtensions.cs +++ b/src/Extensions/StreamExtensions.cs @@ -1,17 +1,28 @@ namespace NSExt.Extensions; +/// +/// StreamExtensions +/// public static class StreamExtensions { + /// + /// FirstByteIndex + /// public static long FirstByteIndex(this Stream me, byte[] findBytes) { int data; - while ((data = me.ReadByte()) != -1) - if (findBytes.Contains((byte)data)) + while ((data = me.ReadByte()) != -1) { + if (findBytes.Contains((byte)data)) { return me.Position; + } + } return -1; } + /// + /// IsTextStream + /// public static bool IsTextStream(this Stream me) { return me.FirstByteIndex(new byte[] { 0x00, 0xff }) < 0; diff --git a/src/Extensions/StringExtensions.cs b/src/Extensions/StringExtensions.cs index c0ef106..d4a6741 100644 --- a/src/Extensions/StringExtensions.cs +++ b/src/Extensions/StringExtensions.cs @@ -1,41 +1,26 @@ // ReSharper disable UnusedMember.Global +// ReSharper disable MemberCanBePrivate.Global - +#pragma warning disable CA1720 using System.Security.Cryptography; using System.Text.Json; namespace NSExt.Extensions; -public static class StringExtensions +/// +/// StringExtensions +/// +public static partial class StringExtensions { private static readonly JsonSerializerOptions _defaultJsonSerializerOptions = default(JsonSerializerOptions).NewJsonSerializerOptions(); - /// - /// MD5 hmac编码 - /// - /// 字符串 - /// 密钥 - /// 字符串使用的编码 - /// hash摘要的16进制文本形式(无连字符小写) - private static string Md5Hmac(this string me, string key, Encoding e) - { - using var md5Hmac = new HMACMD5(e.GetBytes(key)); - return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me))) - .Replace("-", string.Empty) - .ToLower(CultureInfo.CurrentCulture); - } - /// /// aes加密 /// /// 要加密的串 /// 密钥 - /// 指定要用于加密的块密码模式。 - /// 指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型。 - /// - public static string Aes(this string me, string key, CipherMode cipherMode = CipherMode.ECB - , PaddingMode paddingMode = PaddingMode.PKCS7) + public static string Aes(this string me, string key) { using var aes = System.Security.Cryptography.Aes.Create(); aes.Padding = PaddingMode.PKCS7; @@ -47,17 +32,12 @@ public static class StringExtensions return decrypted.Base64(); } - /// /// aes解密 /// /// 要加密的串 /// 密钥 - /// 指定要用于加密的块密码模式。 - /// 指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型。 - /// - public static string AesDe(this string me, string key, CipherMode cipherMode = CipherMode.ECB - , PaddingMode paddingMode = PaddingMode.PKCS7) + public static string AesDe(this string me, string key) { using var aes = System.Security.Cryptography.Aes.Create(); aes.Padding = PaddingMode.PKCS7; @@ -98,13 +78,12 @@ public static class StringExtensions /// 解码后的原始字符串 public static string Base64De(this string me, Encoding e) { - return e.GetString(Base64De(me)); + return e.GetString(me.Base64De()); } /// /// 将易于web传输的base64web字符串转换为原生base64 /// - /// /// 原生base64 public static string Base64Sys(this string me) { @@ -114,7 +93,6 @@ public static class StringExtensions /// /// 将原生base64字符串转换成易于web传输的字符串 /// - /// /// 易于web传输的字符串 public static string Base64Web(this string me) { @@ -156,7 +134,6 @@ public static class StringExtensions : ret; } - /// /// 将字符串转换成日期对象 /// @@ -178,7 +155,6 @@ public static class StringExtensions return decimal.Parse(me, CultureInfo.CurrentCulture); } - /// /// 尝试将字符串转为decimal /// @@ -190,7 +166,6 @@ public static class StringExtensions return !decimal.TryParse(me, out var ret) ? def : ret; } - /// /// string to double /// @@ -204,23 +179,17 @@ public static class StringExtensions /// /// 将字符串转换成枚举对象 /// - /// - /// - /// - public static T Enum(this string name) where T : Enum + public static T Enum(this string name) + where T : Enum { return (T)System.Enum.Parse(typeof(T), name, true); } - /// /// 将字符串转换成枚举对象 /// - /// - /// - /// - /// - public static T EnumTry(this string name, T def) where T : Enum + public static T EnumTry(this string name, T def) + where T : Enum { return !System.Enum.TryParse(typeof(T), name, out var ret) ? def : (T)ret; } @@ -235,12 +204,10 @@ public static class StringExtensions return float.Parse(me, CultureInfo.CurrentCulture); } - /// /// 将字符串转为guid /// /// 字符串 - /// public static Guid Guid(this string me) { return System.Guid.Parse(me); @@ -251,13 +218,11 @@ public static class StringExtensions /// /// 字符串 /// 转换失败的返回值 - /// public static Guid Guid(this string me, Guid def) { return System.Guid.TryParse(me, out var ret) ? ret : def; } - /// /// 将字符串转换成字节数组形式 /// @@ -279,11 +244,10 @@ public static class StringExtensions return me.Hex(Encoding.UTF8); } - /// /// 对一个字符串进行sha1 hash运算 /// - /// 对一个字符串进行sha1 hash运算 + /// me /// 密钥 /// 使用的编码 /// hash摘要的16进制文本形式(无连字符小写) @@ -299,8 +263,6 @@ public static class StringExtensions /// /// html编码 /// - /// - /// public static string Html(this string me) { return HttpUtility.HtmlEncode(me); @@ -337,7 +299,6 @@ public static class StringExtensions return !int.TryParse(me, out var ret) ? def : ret; } - /// /// string to Int64 /// @@ -362,43 +323,43 @@ public static class StringExtensions /// /// ipv4格式转int32格式 /// - /// - /// public static int IpV4ToInt32(this string me) { return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0); } - /// /// 是否base64字符串 /// /// 字符串 - /// public static bool IsBase64String(this string me) { // 一个合法的Base64,有着以下特征: // 字符串的长度为4的整数倍。 // 字符串的符号取值只能在A -Z, a -z, 0 -9, +, /, =共计65个字符中,且 = 如果出现就必须在结尾出现。 - if (!me.All(x => x.IsBase64Character())) return false; - if (me.Length % 4 != 0) return false; + if (!me.All(x => x.IsBase64Character())) { + return false; + } + + if (me.Length % 4 != 0) { + return false; + } + var firstEqualSignPos = me.IndexOf('='); - if (firstEqualSignPos < 0) return true; + if (firstEqualSignPos < 0) { + return true; + } + var lastEqualSignPos = me.LastIndexOf('='); return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '='); } - /// /// 中文姓名打马赛克 /// - /// - /// public static string MaskChineseName(this string me) { - if (me.Length == 2) return "*" + me[1..]; - - return me[..1] + "*" + me[^1..]; + return me.Length == 2 ? "*" + me[1..] : me[..1] + "*" + me[^1..]; } /// @@ -408,10 +369,9 @@ public static class StringExtensions /// 掩码后的手机号 public static string MaskMobile(this string me) { - return new Regex(@"^(\d{3})\d{4}(\d{4})$").Replace(me, "$1****$2"); + return MyRegex().Replace(me, "$1****$2"); } - /// /// 对一个字符串进行md5hash运算 /// @@ -420,8 +380,7 @@ public static class StringExtensions /// hash摘要的16进制文本形式(无连字符小写) public static string Md5(this string me, Encoding e) { - using var md5 = MD5.Create(); - return BitConverter.ToString(md5.ComputeHash(e.GetBytes(me))) + return BitConverter.ToString(MD5.HashData(e.GetBytes(me))) .Replace("-", string.Empty) .ToLower(CultureInfo.CurrentCulture); } @@ -437,12 +396,9 @@ public static class StringExtensions return me.AsEnumerable().NullOrEmpty() ? defVal : me; } - /// /// null或空白字符 /// - /// - /// public static bool NullOrWhiteSpace(this string me) { return string.IsNullOrWhiteSpace(me); @@ -459,7 +415,6 @@ public static class StringExtensions return JsonSerializer.Deserialize(me, options ?? _defaultJsonSerializerOptions); } - /// /// 反序列化一个文件获得指定类型的数据对象 /// @@ -472,7 +427,6 @@ public static class StringExtensions return JsonSerializer.Deserialize(me, type, options ?? _defaultJsonSerializerOptions); } - /// /// 生成密码 /// @@ -490,20 +444,17 @@ public static class StringExtensions /// 处理之后的字符串 public static string RemoveHtmlTag(this string me) { - return new Regex(@"<[^>]*>").Replace(me, ""); + return MyRegex1().Replace(me, string.Empty); } /// /// 删除换行符 /// - /// - /// public static string RemoveWrapped(this string me) { - return me.Replace("\r", "").Replace("\n", ""); + return me.Replace("\r", string.Empty).Replace("\n", string.Empty); } - /// /// 对一个字符串进行sha1 hash运算 /// @@ -512,42 +463,34 @@ public static class StringExtensions /// hash摘要的16进制文本形式(无连字符小写) public static string Sha1(this string me, Encoding e) { - using var sha1 = SHA1.Create(); - return BitConverter.ToString(sha1.ComputeHash(e.GetBytes(me))) + return BitConverter.ToString(SHA1.HashData(e.GetBytes(me))) .Replace("-", string.Empty) .ToLower(CultureInfo.CurrentCulture); } - /// /// 蛇形命名 /// - /// - /// public static string Snakecase(this string me) { - return Regex.Replace(me, "([A-Z])", "-$1").ToLower().TrimStart('-'); + return MyRegex2().Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-'); } - /// /// 截取指定长度的字符串,代替substring /// - /// - /// - /// - /// public static string Sub(this string me, int startIndex, int length) { - if (startIndex + length > me.Length) length = me.Length - startIndex; + if (startIndex + length > me.Length) { + length = me.Length - startIndex; + } + return me.Substring(startIndex, length); } /// /// 纯文本字符串转html /// - /// - /// public static string Text2Html(this string me) { return $"
{me}
"; @@ -556,15 +499,13 @@ public static class StringExtensions /// /// 将连续多个空格替换成一个空格 /// - /// - /// public static string TrimSpaces(this string me) { var ret = me.Replace(" ", " "); - // ReSharper disable once TailRecursiveCall - return ret == me ? ret : TrimSpaces(ret); - } + // ReSharper disable once TailRecursiveCall + return ret == me ? ret : ret.TrimSpaces(); + } /// /// url编码 @@ -585,4 +526,28 @@ public static class StringExtensions { return Uri.UnescapeDataString(me); } + + /// + /// MD5 hmac编码 + /// + /// 字符串 + /// 密钥 + /// 字符串使用的编码 + /// hash摘要的16进制文本形式(无连字符小写) + private static string Md5Hmac(this string me, string key, Encoding e) + { + using var md5Hmac = new HMACMD5(e.GetBytes(key)); + return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me))) + .Replace("-", string.Empty) + .ToLower(CultureInfo.CurrentCulture); + } + + [GeneratedRegex("^(\\d{3})\\d{4}(\\d{4})$")] + private static partial Regex MyRegex(); + + [GeneratedRegex("<[^>]*>")] + private static partial Regex MyRegex1(); + + [GeneratedRegex("([A-Z])")] + private static partial Regex MyRegex2(); } \ No newline at end of file diff --git a/src/Extensions/TypeExtensions.cs b/src/Extensions/TypeExtensions.cs index a8739d0..ea897bc 100644 --- a/src/Extensions/TypeExtensions.cs +++ b/src/Extensions/TypeExtensions.cs @@ -1,13 +1,13 @@ namespace NSExt.Extensions; +/// +/// TypeExtensions +/// public static class TypeExtensions { /// /// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。 /// - /// - /// - /// public static IEnumerable GetCustomAttributesIncludingBaseInterfaces(this Type me) { var attributeType = typeof(T); diff --git a/src/Extensions/UriExtensions.cs b/src/Extensions/UriExtensions.cs index 8b8bb43..6f9377a 100644 --- a/src/Extensions/UriExtensions.cs +++ b/src/Extensions/UriExtensions.cs @@ -1,12 +1,13 @@ namespace NSExt.Extensions; +/// +/// UriExtensions +/// public static class UriExtensions { /// /// 移除url的Scheme /// - /// - /// public static string RemoveScheme(this Uri me) { return "//" + me.Authority + me.PathAndQuery; diff --git a/src/GlobalUsings.cs b/src/GlobalUsings.cs index a5091a5..4893fbf 100644 --- a/src/GlobalUsings.cs +++ b/src/GlobalUsings.cs @@ -1,9 +1,9 @@ +global using System.ComponentModel; global using System.Data; global using System.Data.Common; -global using System.Runtime.CompilerServices; -global using Microsoft.Extensions.Logging; global using System.Globalization; +global using System.Runtime.CompilerServices; global using System.Text; global using System.Text.RegularExpressions; global using System.Web; -global using System.ComponentModel; \ No newline at end of file +global using Microsoft.Extensions.Logging; \ No newline at end of file diff --git a/src/NSExt.csproj b/src/NSExt.csproj index 010dd8d..1196f66 100644 --- a/src/NSExt.csproj +++ b/src/NSExt.csproj @@ -1,16 +1,17 @@ - net6.0;net7.0 + net7.0 + true - + - all - runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file diff --git a/stylecop.json b/stylecop.json new file mode 100644 index 0000000..ae79eec --- /dev/null +++ b/stylecop.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "indentation": { + "useTabs": false, + "indentationSize": 4 + } + } +} \ No newline at end of file From 31e31c5d495862e8bf5a271f45399f2acaf0af4f Mon Sep 17 00:00:00 2001 From: nsnail Date: Thu, 15 Dec 2022 15:49:47 +0800 Subject: [PATCH 2/3] --- README.md | 24 +++++++++++++++++++++++- README.zh-CN.md | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 README.zh-CN.md diff --git a/README.md b/README.md index 90f739e..21bfbe8 100644 --- a/README.md +++ b/README.md @@ -1 +1,23 @@ -# ns-ext \ No newline at end of file +# ns-ext +The **ns-ext** is a .NET extension function library, containing the following types of extension modules: + + +| Features | File name | +| -------- | ---------------------------------- | +| Byte type extension | ByteExtensions.cs | +| Character Type Extensions | CharExtensions.cs | +| Date Type Extensions | DateTimeExtensions.cs | +| Database command type extension | DbCommandExtensions.cs | +| Decimal Number Type extension | DecimalExtensions.cs | +| Enumable type extension | EnumerableExtensions.cs | +| Enumeration type extension | EnumExtensions.cs | +| General type extension | GenericExtensions.cs | +| Integer type extension | IntExtensions.cs | +| Json Serialization option type extension | JsonSerializerOptionsExtensions.cs | +| Log type extension | LoggerExtensions.cs | +| Long integer extension | LongExtensions.cs | +| Object type extension | ObjectExtensions.cs | +| Stream type extension | StreamExtensions.cs | +| String type extension | StringExtensions.cs | +| Prototype type extension | TypeExtensions.cs | +| Resource locator type extension | UriExtensions.cs | \ No newline at end of file diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..48fefd3 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,23 @@ +# ns-ext +**ns-ext** 是一个.NET扩展函数库,包含以下类型扩展模块: + + +| 功能 | 文件名 | +| -------- | ---------------------------------- | +| 字节类型扩展 | ByteExtensions.cs | +| 字符类型扩展 | CharExtensions.cs | +| 日期类型扩展 | DateTimeExtensions.cs | +| 数据库命令类型扩展 | DbCommandExtensions.cs | +| 十进制数类型扩展 | DecimalExtensions.cs | +| 可枚举类型扩展 | EnumerableExtensions.cs | +| 枚举类型扩展 | EnumExtensions.cs | +| 泛型类型扩展 | GenericExtensions.cs | +| 整数型扩展 | IntExtensions.cs | +| Json序列化选项类型扩展 | JsonSerializerOptionsExtensions.cs | +| 日志类型扩展 | LoggerExtensions.cs | +| 长整型扩展 | LongExtensions.cs | +| 对象类型扩展 | ObjectExtensions.cs | +| 流类型扩展 | StreamExtensions.cs | +| 字符串类型扩展 | StringExtensions.cs | +| 原型类型扩展 | TypeExtensions.cs | +| 资源定位符类型扩展 | UriExtensions.cs | \ No newline at end of file From 8c1083f732b6cbaa93a465bd8f807eb1eee0325c Mon Sep 17 00:00:00 2001 From: nsnail Date: Thu, 15 Dec 2022 16:03:02 +0800 Subject: [PATCH 3/3] --- README.md | 44 +++++++++++++++++++++++++++++++++++++++++++- README.zh-CN.md | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21bfbe8..c137c1f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # ns-ext +[中](README.zh-CN.md) | **En** The **ns-ext** is a .NET extension function library, containing the following types of extension modules: @@ -20,4 +21,45 @@ The **ns-ext** is a .NET extension function library, containing the following ty | Stream type extension | StreamExtensions.cs | | String type extension | StringExtensions.cs | | Prototype type extension | TypeExtensions.cs | -| Resource locator type extension | UriExtensions.cs | \ No newline at end of file +| Resource locator type extension | UriExtensions.cs | + +## Quick start + +### Install + +```shell +dotnet add package NSExt --prerelease +``` + +### Example + +```c# +using NSExt.Extensions; + +internal static class Program +{ + private class Person + { + public string Name { get; set; } + public int Age { get; set; } + } + public static void Main(string[] args) + { + var person = + """ +{ + "Name": "Jason", + "Age": "30" +} +""".Object(); + + Console.WriteLine(person.Json()); + } +} +``` + +### Output + +```json +{"name":"Jason","age":30} +``` \ No newline at end of file diff --git a/README.zh-CN.md b/README.zh-CN.md index 48fefd3..127d239 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,4 +1,5 @@ # ns-ext +[En](README.md) | **中** **ns-ext** 是一个.NET扩展函数库,包含以下类型扩展模块: @@ -20,4 +21,45 @@ | 流类型扩展 | StreamExtensions.cs | | 字符串类型扩展 | StringExtensions.cs | | 原型类型扩展 | TypeExtensions.cs | -| 资源定位符类型扩展 | UriExtensions.cs | \ No newline at end of file +| 资源定位符类型扩展 | UriExtensions.cs | + +## 快速开始 + +### 安装 + +```shell +dotnet add package NSExt --prerelease +``` + +### 示例 + +```c# +using NSExt.Extensions; + +internal static class Program +{ + private class Person + { + public string Name { get; set; } + public int Age { get; set; } + } + public static void Main(string[] args) + { + var person = + """ +{ + "Name": "Jason", + "Age": "30" +} +""".Object(); + + Console.WriteLine(person.Json()); + } +} +``` + +### 输出 + +```json +{"name":"Jason","age":30} +``` \ No newline at end of file