diff --git a/.editorconfig b/.editorconfig index d54638d..8f642da 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,22 +10,31 @@ indent_style = space insert_final_newline = false trim_trailing_whitespace = true +[{*.json,*.yml}] +indent_size = 2 + [*.cs] dotnet_analyzer_diagnostic.severity = warning +dotnet_diagnostic.CA1200.severity = none dotnet_diagnostic.CA1707.severity = none dotnet_diagnostic.CA1716.severity = none -dotnet_diagnostic.CA1848.severity = none -dotnet_diagnostic.CA2254.severity = none -dotnet_diagnostic.CA5350.severity = none -dotnet_diagnostic.CA5351.severity = none dotnet_diagnostic.IDE0005.severity = none dotnet_diagnostic.IDE0008.severity = none dotnet_diagnostic.IDE0010.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 +dotnet_diagnostic.IDE0270.severity = none +dotnet_diagnostic.RCS1141.severity = none +dotnet_diagnostic.RCS1142.severity = none +dotnet_diagnostic.RCS1181.severity = none +dotnet_diagnostic.RCS1186.severity = none +dotnet_diagnostic.S101.severity = none +dotnet_diagnostic.S1121.severity = none +dotnet_diagnostic.S1199.severity = none +dotnet_diagnostic.S125.severity = none +dotnet_diagnostic.S2094.severity = none +dotnet_diagnostic.S3925.severity = none +dotnet_diagnostic.S4663.severity = none dotnet_diagnostic.SYSLIB1045.severity = none diff --git a/CodeQuality.props b/CodeQuality.props deleted file mode 100644 index 314e91e..0000000 --- a/CodeQuality.props +++ /dev/null @@ -1,21 +0,0 @@ - - - ../../StyleCopAnalyzers.ruleset - true - true - true - true - true - true - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file diff --git a/NSExt.sln b/NSExt.sln index 107b0bd..45e3c42 100644 --- a/NSExt.sln +++ b/NSExt.sln @@ -12,20 +12,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-F AddMetaFilesToSln.csx = AddMetaFilesToSln.csx build.cake = build.cake code-format.cmd = code-format.cmd + code.quality.props = code.quality.props CodeCleanupOnSave.csx = CodeCleanupOnSave.csx - CodeQuality.props = CodeQuality.props Directory.Build.props = Directory.Build.props dotnet-tools.json = dotnet-tools.json git-clean.cmd = git-clean.cmd global.json = global.json ImageOptimize.csx = ImageOptimize.csx + key.snk = key.snk LICENSE = LICENSE + logo.png = logo.png NSExt.sln.DotSettings = NSExt.sln.DotSettings NSExt.sln.DotSettings.user = NSExt.sln.DotSettings.user README.md = README.md README.zh-CN.md = README.zh-CN.md + stylecop.analyzers.ruleset = stylecop.analyzers.ruleset stylecop.json = stylecop.json - StyleCopAnalyzers.ruleset = StyleCopAnalyzers.ruleset EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt.Tests", "src\NSExt.Tests\NSExt.Tests.csproj", "{557FBEF6-E6D5-4531-86DF-D772A10E2261}" diff --git a/code.quality.props b/code.quality.props new file mode 100644 index 0000000..b9f7446 --- /dev/null +++ b/code.quality.props @@ -0,0 +1,41 @@ + + + $(SolutionDir)/stylecop.analyzers.ruleset + true + true + true + true + true + true + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/src/NSExt/Attributes/LocalizationAttribute.cs b/src/NSExt/Attributes/LocalizationAttribute.cs index 5658339..9b53058 100644 --- a/src/NSExt/Attributes/LocalizationAttribute.cs +++ b/src/NSExt/Attributes/LocalizationAttribute.cs @@ -4,7 +4,7 @@ namespace NSExt.Attributes; /// 指定本地化资源类型 /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)] -public class LocalizationAttribute : Attribute +public sealed class LocalizationAttribute : Attribute { /// /// Initializes a new instance of the class. diff --git a/src/NSExt/Attributes/ResourceDescriptionAttribute.cs b/src/NSExt/Attributes/ResourceDescriptionAttribute.cs index 8727c95..f124234 100644 --- a/src/NSExt/Attributes/ResourceDescriptionAttribute.cs +++ b/src/NSExt/Attributes/ResourceDescriptionAttribute.cs @@ -4,7 +4,7 @@ namespace NSExt.Attributes; /// 本地化资源描述特性 /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)] -public class ResourceDescriptionAttribute : Attribute +public sealed class ResourceDescriptionAttribute : Attribute { /// /// Initializes a new instance of the class. diff --git a/src/NSExt/Constant/Regexes.cs b/src/NSExt/Constant/Regexes.cs index ec823f0..588297e 100644 --- a/src/NSExt/Constant/Regexes.cs +++ b/src/NSExt/Constant/Regexes.cs @@ -1,7 +1,9 @@ namespace NSExt.Constant; #pragma warning disable SYSLIB1045 -// 使用 RegexGenerator 新特性会生成重复key值的xmlcomment导致出错 +/// +/// 使用 RegexGenerator 新特性会生成重复key值的xmlcomment导致出错 +/// internal static class Regexes { public static readonly Regex RegexBacksLantUnicode diff --git a/src/NSExt/Extensions/ByteExtensions.cs b/src/NSExt/Extensions/ByteExtensions.cs index 08ca075..5c810e0 100644 --- a/src/NSExt/Extensions/ByteExtensions.cs +++ b/src/NSExt/Extensions/ByteExtensions.cs @@ -50,10 +50,10 @@ public static class ByteExtensions var i = 0; foreach (var c in me.Select(x => x.ToString(upperCase ? "X2" : "x2", CultureInfo.InvariantCulture))) { if (i++ % splitInterval == 0) { - sb.Append(splitShar); + _ = sb.Append(splitShar); } - sb.Append(c); + _ = sb.Append(c); } return sb.ToString(); diff --git a/src/NSExt/Extensions/DateTimeExtensions.cs b/src/NSExt/Extensions/DateTimeExtensions.cs index ffebbe5..1d486e8 100644 --- a/src/NSExt/Extensions/DateTimeExtensions.cs +++ b/src/NSExt/Extensions/DateTimeExtensions.cs @@ -1,8 +1,7 @@ // ReSharper disable InconsistentNaming // ReSharper disable UnusedMember.Global -#pragma warning disable SA1300 -#pragma warning disable IDE1006 +#pragma warning disable SA1300, IDE1006 namespace NSExt.Extensions; /// @@ -10,19 +9,6 @@ namespace NSExt.Extensions; /// public static class DateTimeExtensions { - /// - /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前 - /// - /// me - /// 字符串 - public static string TimeAgo(this DateTime me) - { - var ts = DateTime.Now - me; - return ts.Days > 0 ? ts.Days + "天前" : - ts.Hours > 0 ? ts.Hours + "小时前" : - ts.Minutes > 0 ? ts.Minutes + "分钟前" : ts.Seconds + "秒前"; - } - /// /// 指定时间的世界协调时的unix时间戳形式 /// @@ -49,6 +35,23 @@ public static class DateTimeExtensions return me.ToString(CultureInfo.InvariantCulture); } + /// + /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前 + /// + /// me + /// 字符串 + public static string UtcTimeAgo(this DateTime me) + { + var ts = DateTime.UtcNow - me; + return ts.Days switch { + > 0 => ts.Days + "天前" + , _ => ts.Hours switch { + > 0 => ts.Hours + "小时前" + , _ => ts.Minutes switch { > 0 => ts.Minutes + "分钟前", _ => ts.Seconds + "秒前" } + } + }; + } + /// /// yyyy_MM /// diff --git a/src/NSExt/Extensions/DbCommandExtensions.cs b/src/NSExt/Extensions/DbCommandExtensions.cs index d72fa49..62b4521 100644 --- a/src/NSExt/Extensions/DbCommandExtensions.cs +++ b/src/NSExt/Extensions/DbCommandExtensions.cs @@ -10,7 +10,6 @@ public static class DbCommandExtensions /// public static string ParameterFormat(this DbCommand me) { - // var aa = pars.ToDictionary(it => it.ParameterName, it => it.Value); var sql = me.CommandText; // 应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10 @@ -24,7 +23,10 @@ public static class DbCommandExtensions 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") + , me.Parameters[i].Value != DBNull.Value && + Convert.ToBoolean(me.Parameters[i].Value, CultureInfo.InvariantCulture) + ? "1" + : "0") , _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString()) }; } diff --git a/src/NSExt/Extensions/DecimalExtensions.cs b/src/NSExt/Extensions/DecimalExtensions.cs index 734a2b0..7f6f46e 100644 --- a/src/NSExt/Extensions/DecimalExtensions.cs +++ b/src/NSExt/Extensions/DecimalExtensions.cs @@ -13,8 +13,7 @@ public static class DecimalExtensions /// 处理后的值 public static decimal Round(this decimal me, int place) { - var dec = Math.Round(me, place); - return dec; + return Math.Round(me, place); } /// diff --git a/src/NSExt/Extensions/EnumExtensions.cs b/src/NSExt/Extensions/EnumExtensions.cs index d33f5b5..b40f675 100644 --- a/src/NSExt/Extensions/EnumExtensions.cs +++ b/src/NSExt/Extensions/EnumExtensions.cs @@ -9,35 +9,6 @@ namespace NSExt.Extensions; /// public static class EnumExtensions { - /// - /// 获取枚举的description属性 - /// - /// 枚举对象 - /// description属性 - [Obsolete(nameof(ResDesc))] - public static string Desc(this Enum e) - { - var typeOfEnum = e.GetType(); - var typeOfField = typeOfEnum.GetField(Enum.GetName(typeOfEnum, e)!); - var descAttr = typeOfField!.GetCustomAttribute(true); - if (descAttr is null) { - return Enum.GetName(typeOfEnum, e); - } - - var str = descAttr.Description; - var locAttr = typeOfField!.GetCustomAttribute(true); - return locAttr is null ? str : locAttr.ResourceClass.GetProperty(str)?.GetValue(default) as string ?? str; - } - - /// - /// 通过类泛型类型获取特性 - /// - public static T GetAttributeOfType(this Enum me) - where T : Attribute - { - return me.GetType().GetMember(me.ToString()).First().GetCustomAttributes(false).FirstOrDefault(); - } - /// /// 获取显示特性 /// @@ -58,4 +29,13 @@ public static class EnumExtensions ? Enum.GetName(typeOfEnum, e) : typeof(T).GetProperty(resDescAttr.ResourceName)?.GetValue(default) as string; } + + /// + /// 通过类泛型类型获取特性 + /// + private static T GetAttributeOfType(this Enum me) + where T : Attribute + { + return me.GetType().GetMember(me.ToString())[0].GetCustomAttributes(false).FirstOrDefault(); + } } \ No newline at end of file diff --git a/src/NSExt/Extensions/EnumerableExtensions.cs b/src/NSExt/Extensions/EnumerableExtensions.cs index c6496c8..08eef9f 100644 --- a/src/NSExt/Extensions/EnumerableExtensions.cs +++ b/src/NSExt/Extensions/EnumerableExtensions.cs @@ -21,6 +21,6 @@ public static class EnumerableExtensions /// 空则返回true public static bool NullOrEmpty(this IEnumerable me) { - return me is null || !me.Any(); + return me?.Any() != true; } } \ No newline at end of file diff --git a/src/NSExt/Extensions/LongExtensions.cs b/src/NSExt/Extensions/LongExtensions.cs index bf3b605..6ea66b9 100644 --- a/src/NSExt/Extensions/LongExtensions.cs +++ b/src/NSExt/Extensions/LongExtensions.cs @@ -29,7 +29,7 @@ public static class LongExtensions /// public static DateTime Time(this long msFrom1970) { - return new DateTime(1970, 1, 1).AddMilliseconds(msFrom1970).ToLocalTime(); + return DateTime.UnixEpoch.AddMilliseconds(msFrom1970).ToLocalTime(); } /// diff --git a/src/NSExt/Extensions/StringExtensions.cs b/src/NSExt/Extensions/StringExtensions.cs index ea9c1a1..17e37dc 100644 --- a/src/NSExt/Extensions/StringExtensions.cs +++ b/src/NSExt/Extensions/StringExtensions.cs @@ -141,7 +141,7 @@ public static class StringExtensions /// 转换后的日期对象 public static DateTime DateTimeTry(this string me, DateTime def) { - return !System.DateTime.TryParse(me, out var ret) ? def : ret; + return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, out var ret) ? def : ret; } /// @@ -252,7 +252,9 @@ public static class StringExtensions /// hash摘要的16进制文本形式(无连字符小写) public static string HmacSha1(this string me, string secret, Encoding e) { + #pragma warning disable CA5350 using var hmacSha1 = new HMACSHA1(e.GetBytes(secret)); + #pragma warning restore CA5350 return BitConverter.ToString(hmacSha1.ComputeHash(e.GetBytes(me))) .Replace("-", string.Empty) @@ -379,7 +381,9 @@ public static class StringExtensions /// hash摘要的16进制文本形式(无连字符小写) public static string Md5(this string me, Encoding e) { + #pragma warning disable CA5351 return BitConverter.ToString(MD5.HashData(e.GetBytes(me))) + #pragma warning restore CA5351 .Replace("-", string.Empty) .ToLower(CultureInfo.CurrentCulture); } @@ -462,7 +466,9 @@ public static class StringExtensions /// hash摘要的16进制文本形式(无连字符小写) public static string Sha1(this string me, Encoding e) { + #pragma warning disable CA5350 return BitConverter.ToString(SHA1.HashData(e.GetBytes(me))) + #pragma warning restore CA5350 .Replace("-", string.Empty) .ToLower(CultureInfo.CurrentCulture); } @@ -531,8 +537,18 @@ public static class StringExtensions public static string UnicodeDe(this string me) { const string replacement = "&#x$1;"; - return me.Contains(@"\u") ? Regexes.RegexBacksLantUnicode.Replace(me, replacement).HtmlDe() : - me.Contains(@"%u") ? Regexes.RegexPercentUnicode.Replace(me, replacement).HtmlDe() : me.HtmlDe(); + if (me.Contains(@"\u")) { + return Regexes.RegexBacksLantUnicode.Replace(me, replacement).HtmlDe(); + } + + // ReSharper disable once ConvertIfStatementToReturnStatement + #pragma warning disable IDE0046 + if (me.Contains("%u")) { + #pragma warning restore IDE0046 + return Regexes.RegexPercentUnicode.Replace(me, replacement).HtmlDe(); + } + + return me.HtmlDe(); } /// @@ -564,7 +580,9 @@ public static class StringExtensions /// hash摘要的16进制文本形式(无连字符小写) private static string Md5Hmac(this string me, string key, Encoding e) { + #pragma warning disable CA5351 using var md5Hmac = new HMACMD5(e.GetBytes(key)); + #pragma warning restore CA5351 return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me))) .Replace("-", string.Empty) .ToLower(CultureInfo.CurrentCulture); diff --git a/src/NSExt/GlobalUsings.cs b/src/NSExt/GlobalUsings.cs index 4893fbf..ce9e85d 100644 --- a/src/NSExt/GlobalUsings.cs +++ b/src/NSExt/GlobalUsings.cs @@ -1,4 +1,3 @@ -global using System.ComponentModel; global using System.Data; global using System.Data.Common; global using System.Globalization; diff --git a/src/NSExt/NSExt.csproj b/src/NSExt/NSExt.csproj index 5b63f16..250cd45 100644 --- a/src/NSExt/NSExt.csproj +++ b/src/NSExt/NSExt.csproj @@ -1,5 +1,5 @@ - + ../../key.snk false diff --git a/stylecop.analyzers.ruleset b/stylecop.analyzers.ruleset new file mode 100644 index 0000000..b8faaff --- /dev/null +++ b/stylecop.analyzers.ruleset @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file