5 Commits

Author SHA1 Message Date
tk
f2444b3048 feat: enum、string 2023-02-27 11:03:19 +08:00
d1978d9d9e <chore> 2023-02-08 22:20:16 +08:00
1f17375915 feat: * 泛型特性本地化资源描述 * 添加测试项目 2023-02-08 22:15:56 +08:00
f846b7bdbf 调整一下日志格式 2023-01-29 20:32:58 +08:00
9384bc0692 <chore> 2023-01-19 20:35:34 +08:00
40 changed files with 489 additions and 375 deletions

View File

@ -13,15 +13,20 @@ trim_trailing_whitespace = true
[*.cs] [*.cs]
dotnet_analyzer_diagnostic.severity = warning dotnet_analyzer_diagnostic.severity = warning
dotnet_diagnostic.CA1707.severity = none dotnet_diagnostic.CA1707.severity = none
dotnet_diagnostic.CA1720.severity = none dotnet_diagnostic.CA1716.severity = none
dotnet_diagnostic.CA1848.severity = none
dotnet_diagnostic.CA2254.severity = none
dotnet_diagnostic.CA5350.severity = none dotnet_diagnostic.CA5350.severity = none
dotnet_diagnostic.CA5351.severity = none dotnet_diagnostic.CA5351.severity = none
dotnet_diagnostic.IDE0005.severity = none
dotnet_diagnostic.IDE0008.severity = none dotnet_diagnostic.IDE0008.severity = none
dotnet_diagnostic.IDE0010.severity = none
dotnet_diagnostic.IDE0017.severity = none dotnet_diagnostic.IDE0017.severity = none
dotnet_diagnostic.IDE0048.severity = none dotnet_diagnostic.IDE0048.severity = none
dotnet_diagnostic.IDE0055.severity = none dotnet_diagnostic.IDE0055.severity = none
dotnet_diagnostic.IDE0058.severity = none dotnet_diagnostic.IDE0058.severity = none
dotnet_diagnostic.IDE0160.severity = none dotnet_diagnostic.IDE0160.severity = none
dotnet_diagnostic.SYSLIB1045.severity = none
# ReSharper properties # ReSharper properties

4
.gitignore vendored
View File

@ -29,7 +29,7 @@ x86/
bld/ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
[Ll]og/ # [Ll]og/
[Ll]ogs/ [Ll]ogs/
# Visual Studio 2015/2017 cache/options directory # Visual Studio 2015/2017 cache/options directory
@ -399,6 +399,6 @@ FodyWeavers.xsd
.idea/ .idea/
# User Define # User Define
build/ dist/
nuget.config nuget.config
*.[Dd]esigner.cs *.[Dd]esigner.cs

View File

@ -1,16 +1,27 @@
#r "nuget: Newtonsoft.Json, 13.0.0"
using System.Xml;
using System.IO;
using Newtonsoft.Json.Linq;
var path = Directory.GetFiles(@".idea", "workspace.xml", SearchOption.AllDirectories).First(); var path = Directory.GetFiles(@".idea", "workspace.xml", SearchOption.AllDirectories).First();
const string findStr = """ XmlDocument xdoc = new XmlDocument();
&quot;keyToString&quot;: { using(var fs = File.Open(path, FileMode.Open)){
"""; xdoc.Load(fs);
const string replaceStr = """ fs.Seek(0, SeekOrigin.Begin);
&quot;keyToString&quot;: { var propertiesComponent = xdoc.SelectSingleNode("""//component[@name="PropertiesComponent"]""");
&quot;rider.code.cleanup.on.save&quot;: &quot;true&quot;, var jsonStr = propertiesComponent.InnerText;
"""; var jsonObj = JObject.Parse(jsonStr);
var content = File.ReadAllText(path); var keyToStringObj = jsonObj["keyToString"] as JObject;
if(content.Contains("rider.code.cleanup.on.save")){ if (keyToStringObj.ContainsKey("rider.code.cleanup.on.save")) return;
Console.WriteLine("alreay added");
return; keyToStringObj.Add(new JProperty("rider.code.cleanup.on.save", "true"));
} var newNode = xdoc.CreateCDataSection(jsonObj.ToString());
content = content.Replace(findStr, replaceStr); propertiesComponent.InnerText=string.Empty;
Console.WriteLine(content); propertiesComponent.AppendChild(newNode);
File.WriteAllText(path, content); var settings = new XmlWriterSettings { Indent = true };
using(var writer = XmlWriter.Create(fs, settings)){
xdoc.WriteTo(writer);
}
}

View File

@ -1,6 +1,6 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<CodeAnalysisRuleSet>../StyleCopAnalyzers.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>../../StyleCopAnalyzers.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors> <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors> <MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
@ -13,5 +13,9 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="NSCodeAnalysis" Version="1.0.1-alpha.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,22 +1,13 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings> <!-- $(XXX) 定义有顺序 排序请注意-->
<BaseOutputPath>../dist</BaseOutputPath> <SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
<BaseIntermediateOutputPath>../dist</BaseIntermediateOutputPath>
<OutputPath>$(BaseOutputPath)/$(MSBuildProjectName)/bin</OutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj</IntermediateOutputPath>
<MSBuildProjectExtensionsPath>$(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj</MSBuildProjectExtensionsPath>
<Authors>nsnail</Authors> <Authors>nsnail</Authors>
<Product>NSExt</Product> <BaseIntermediateOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath>
<Copyright>© 2006-2022 nsnail</Copyright> <BaseOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/bin</BaseOutputPath>
<RepositoryUrl>https://github.com/nsnail/ns-ext.git</RepositoryUrl> <Copyright>© 2006-2023 nsnail</Copyright>
<PublishRepositoryUrl>true</PublishRepositoryUrl> <EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning>
<EmbedUntrackedSource>true</EmbedUntrackedSource> <ImplicitUsings>enable</ImplicitUsings>
<EmbedAllSources>true</EmbedAllSources> <TargetFramework>net7.0</TargetFramework>
<RepositoryType>Git</RepositoryType>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/nsnail/ns-ext.git</PackageProjectUrl>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59 VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt.csproj", "{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-FC0A-4C1D-92DE-38D0662C257D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-FC0A-4C1D-92DE-38D0662C257D}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
@ -17,18 +15,23 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-F
CodeCleanupOnSave.csx = CodeCleanupOnSave.csx CodeCleanupOnSave.csx = CodeCleanupOnSave.csx
CodeQuality.props = CodeQuality.props CodeQuality.props = CodeQuality.props
Directory.Build.props = Directory.Build.props Directory.Build.props = Directory.Build.props
dot.sln.DotSettings = dot.sln.DotSettings
dotnet-tools.json = dotnet-tools.json dotnet-tools.json = dotnet-tools.json
git-clean.cmd = git-clean.cmd git-clean.cmd = git-clean.cmd
global.json = global.json global.json = global.json
ImageOptimize.csx = ImageOptimize.csx ImageOptimize.csx = ImageOptimize.csx
LICENSE = LICENSE LICENSE = LICENSE
push2nuget.ps1 = push2nuget.ps1 NSExt.sln.DotSettings = NSExt.sln.DotSettings
NSExt.sln.DotSettings.user = NSExt.sln.DotSettings.user
README.md = README.md README.md = README.md
README.zh-CN.md = README.zh-CN.md
stylecop.json = stylecop.json stylecop.json = stylecop.json
StyleCopAnalyzers.ruleset = StyleCopAnalyzers.ruleset StyleCopAnalyzers.ruleset = StyleCopAnalyzers.ruleset
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt.Tests", "src\NSExt.Tests\NSExt.Tests.csproj", "{557FBEF6-E6D5-4531-86DF-D772A10E2261}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt\NSExt.csproj", "{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -38,9 +41,13 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Debug|Any CPU.Build.0 = Debug|Any CPU {557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Release|Any CPU.ActiveCfg = Release|Any CPU {557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Release|Any CPU.Build.0 = Release|Any CPU {557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.Build.0 = Release|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,4 +1,7 @@
<wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve"> <wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve">
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64> <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64> <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
@ -12,7 +15,6 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-16"?&gt; <s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"&gt; &lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"&gt;
&lt;TypePattern&gt; &lt;TypePattern&gt;

View File

@ -13,7 +13,7 @@
<Rule Id="SA1002" Action="Warning"/> <!-- Semicolons should be spaced correctly --> <Rule Id="SA1002" Action="Warning"/> <!-- Semicolons should be spaced correctly -->
<Rule Id="SA1003" Action="Warning"/> <!-- Symbols should be spaced correctly --> <Rule Id="SA1003" Action="Warning"/> <!-- Symbols should be spaced correctly -->
<Rule Id="SA1004" Action="Warning"/> <!-- Documentation lines should begin with single space --> <Rule Id="SA1004" Action="Warning"/> <!-- Documentation lines should begin with single space -->
<Rule Id="SA1005" Action="None"/> <!-- Single line comments should begin with single space --> <Rule Id="SA1005" Action="Warning"/> <!-- Single line comments should begin with single space -->
<Rule Id="SA1006" Action="Warning"/> <!-- Preprocessor keywords should not be preceded by space --> <Rule Id="SA1006" Action="Warning"/> <!-- Preprocessor keywords should not be preceded by space -->
<Rule Id="SA1007" Action="Warning"/> <!-- Operator keyword should be followed by space --> <Rule Id="SA1007" Action="Warning"/> <!-- Operator keyword should be followed by space -->
<Rule Id="SA1008" Action="None"/> <!-- Opening parenthesis should be spaced correctly --> <Rule Id="SA1008" Action="None"/> <!-- Opening parenthesis should be spaced correctly -->
@ -73,7 +73,7 @@
<Rule Id="SA1131" Action="Warning"/> <!-- Use readable conditions --> <Rule Id="SA1131" Action="Warning"/> <!-- Use readable conditions -->
<Rule Id="SA1132" Action="Warning"/> <!-- Do not combine fields --> <Rule Id="SA1132" Action="Warning"/> <!-- Do not combine fields -->
<Rule Id="SA1133" Action="Warning"/> <!-- Do not combine attributes --> <Rule Id="SA1133" Action="Warning"/> <!-- Do not combine attributes -->
<Rule Id="SA1134" Action="None"/> <!-- Attributes should not share line --> <Rule Id="SA1134" Action="Warning"/> <!-- Attributes should not share line -->
<Rule Id="SA1135" Action="Warning"/> <!-- Using directives should be qualified --> <Rule Id="SA1135" Action="Warning"/> <!-- Using directives should be qualified -->
<Rule Id="SA1136" Action="Warning"/> <!-- Enum values should be on separate lines --> <Rule Id="SA1136" Action="Warning"/> <!-- Enum values should be on separate lines -->
<Rule Id="SA1137" Action="Warning"/> <!-- Elements should have the same indentation --> <Rule Id="SA1137" Action="Warning"/> <!-- Elements should have the same indentation -->
@ -115,7 +115,7 @@
<Rule Id="SA1310" Action="None"/> <!-- Field names should not contain underscore --> <Rule Id="SA1310" Action="None"/> <!-- Field names should not contain underscore -->
<Rule Id="SA1311" Action="Warning"/> <!-- Static readonly fields should begin with upper-case letter --> <Rule Id="SA1311" Action="Warning"/> <!-- Static readonly fields should begin with upper-case letter -->
<Rule Id="SA1312" Action="Warning"/> <!-- Variable names should begin with lower-case letter --> <Rule Id="SA1312" Action="Warning"/> <!-- Variable names should begin with lower-case letter -->
<Rule Id="SA1313" Action="None"/> <!-- Parameter names should begin with lower-case letter --> <Rule Id="SA1313" Action="Warning"/> <!-- Parameter names should begin with lower-case letter -->
<Rule Id="SA1314" Action="Warning"/> <!-- Type parameter names should begin with T --> <Rule Id="SA1314" Action="Warning"/> <!-- Type parameter names should begin with T -->
<Rule Id="SX1309" Action="Warning"/> <!-- Field names should begin with underscore --> <Rule Id="SX1309" Action="Warning"/> <!-- Field names should begin with underscore -->
<Rule Id="SX1309S" Action="Warning"/> <!-- Static field names should begin with underscore --> <Rule Id="SX1309S" Action="Warning"/> <!-- Static field names should begin with underscore -->
@ -125,12 +125,12 @@
<Rule Id="SA1119" Action="Warning"/> <!-- Statement should not use unnecessary parenthesis --> <Rule Id="SA1119" Action="Warning"/> <!-- Statement should not use unnecessary parenthesis -->
<Rule Id="SA1400" Action="Warning"/> <!-- Access modifier should be declared --> <Rule Id="SA1400" Action="Warning"/> <!-- Access modifier should be declared -->
<Rule Id="SA1401" Action="Warning"/> <!-- Fields should be private --> <Rule Id="SA1401" Action="Warning"/> <!-- Fields should be private -->
<Rule Id="SA1402" Action="Warning"/> <!-- File may only contain a single type --> <Rule Id="SA1402" Action="None"/> <!-- File may only contain a single type -->
<Rule Id="SA1403" Action="Warning"/> <!-- File may only contain a single namespace --> <Rule Id="SA1403" Action="Warning"/> <!-- File may only contain a single namespace -->
<Rule Id="SA1404" Action="Warning"/> <!-- Code analysis suppression should have justification --> <Rule Id="SA1404" Action="Warning"/> <!-- Code analysis suppression should have justification -->
<Rule Id="SA1405" Action="Warning"/> <!-- Debug.Assert should provide message text --> <Rule Id="SA1405" Action="Warning"/> <!-- Debug.Assert should provide message text -->
<Rule Id="SA1406" Action="Warning"/> <!-- Debug.Fail should provide message text --> <Rule Id="SA1406" Action="Warning"/> <!-- Debug.Fail should provide message text -->
<Rule Id="SA1407" Action="None"/> <!-- Arithmetic expressions should declare precedence --> <Rule Id="SA1407" Action="Warning"/> <!-- Arithmetic expressions should declare precedence -->
<Rule Id="SA1408" Action="Warning"/> <!-- Conditional expressions should declare precedence --> <Rule Id="SA1408" Action="Warning"/> <!-- Conditional expressions should declare precedence -->
<Rule Id="SA1409" Action="Warning"/> <!-- Remove unnecessary code --> <Rule Id="SA1409" Action="Warning"/> <!-- Remove unnecessary code -->
<Rule Id="SA1410" Action="Warning"/> <!-- Remove delegate parenthesis when possible --> <Rule Id="SA1410" Action="Warning"/> <!-- Remove delegate parenthesis when possible -->
@ -143,7 +143,7 @@
<Rule Id="SA1500" Action="None"/> <!-- Braces for multi-line statements should not share line --> <Rule Id="SA1500" Action="None"/> <!-- Braces for multi-line statements should not share line -->
<Rule Id="SA1501" Action="Warning"/> <!-- Statement should not be on a single line --> <Rule Id="SA1501" Action="Warning"/> <!-- Statement should not be on a single line -->
<Rule Id="SA1502" Action="None"/> <!-- Element should not be on a single line --> <Rule Id="SA1502" Action="None"/> <!-- Element should not be on a single line -->
<Rule Id="SA1503" Action="None"/> <!-- Braces should not be omitted --> <Rule Id="SA1503" Action="Warning"/> <!-- Braces should not be omitted -->
<Rule Id="SA1504" Action="Warning"/> <!-- All accessors should be single-line or multi-line --> <Rule Id="SA1504" Action="Warning"/> <!-- All accessors should be single-line or multi-line -->
<Rule Id="SA1505" Action="Warning"/> <!-- Opening braces should not be followed by blank line --> <Rule Id="SA1505" Action="Warning"/> <!-- Opening braces should not be followed by blank line -->
<Rule Id="SA1506" Action="Warning"/> <!-- Element documentation headers should not be followed by blank line --> <Rule Id="SA1506" Action="Warning"/> <!-- Element documentation headers should not be followed by blank line -->
@ -173,7 +173,7 @@
<Rule Id="SA1606" Action="Warning"/> <!-- Element documentation should have summary text --> <Rule Id="SA1606" Action="Warning"/> <!-- Element documentation should have summary text -->
<Rule Id="SA1607" Action="Warning"/> <!-- Partial element documentation should have summary text --> <Rule Id="SA1607" Action="Warning"/> <!-- Partial element documentation should have summary text -->
<Rule Id="SA1608" Action="Warning"/> <!-- Element documentation should not have default summary --> <Rule Id="SA1608" Action="Warning"/> <!-- Element documentation should not have default summary -->
<Rule Id="SA1609" Action="Warning"/> <!-- Property documentation should have value --> <Rule Id="SA1609" Action="None"/> <!-- Property documentation should have value -->
<Rule Id="SA1610" Action="Warning"/> <!-- Property documentation should have value text --> <Rule Id="SA1610" Action="Warning"/> <!-- Property documentation should have value text -->
<Rule Id="SA1611" Action="None"/> <!-- Element parameters should be documented --> <Rule Id="SA1611" Action="None"/> <!-- Element parameters should be documented -->
<Rule Id="SA1612" Action="Warning"/> <!-- Element parameter documentation should match element parameters --> <Rule Id="SA1612" Action="Warning"/> <!-- Element parameter documentation should match element parameters -->
@ -187,13 +187,13 @@
<Rule Id="SA1620" Action="Warning"/> <!-- Generic type parameter documentation should match type parameters --> <Rule Id="SA1620" Action="Warning"/> <!-- Generic type parameter documentation should match type parameters -->
<Rule Id="SA1621" Action="Warning"/> <!-- Generic type parameter documentation should declare parameter name --> <Rule Id="SA1621" Action="Warning"/> <!-- Generic type parameter documentation should declare parameter name -->
<Rule Id="SA1622" Action="Warning"/> <!-- Generic type parameter documentation should have text --> <Rule Id="SA1622" Action="Warning"/> <!-- Generic type parameter documentation should have text -->
<Rule Id="SA1623" Action="Warning"/> <!-- Property summary documentation should match accessors --> <Rule Id="SA1623" Action="None"/> <!-- Property summary documentation should match accessors -->
<Rule Id="SA1624" Action="Warning"/> <!-- Property summary documentation should omit accessor with restricted access --> <Rule Id="SA1624" Action="Warning"/> <!-- Property summary documentation should omit accessor with restricted access -->
<Rule Id="SA1625" Action="Warning"/> <!-- Element documentation should not be copied and pasted --> <Rule Id="SA1625" Action="Warning"/> <!-- Element documentation should not be copied and pasted -->
<Rule Id="SA1626" Action="Warning"/> <!-- Single-line comments should not use documentation style slashes --> <Rule Id="SA1626" Action="Warning"/> <!-- Single-line comments should not use documentation style slashes -->
<Rule Id="SA1627" Action="Warning"/> <!-- Documentation text should not be empty --> <Rule Id="SA1627" Action="Warning"/> <!-- Documentation text should not be empty -->
<Rule Id="SA1628" Action="Warning"/> <!-- Documentation text should begin with a capital letter --> <Rule Id="SA1628" Action="Warning"/> <!-- Documentation text should begin with a capital letter -->
<Rule Id="SA1629" Action="None"/> <!-- Documentation text should end with a period --> <Rule Id="SA1629" Action="None"/> <!-- Documentation text should end with a period -->
<Rule Id="SA1630" Action="Warning"/> <!-- Documentation text should contain whitespace --> <Rule Id="SA1630" Action="Warning"/> <!-- Documentation text should contain whitespace -->
<Rule Id="SA1631" Action="Warning"/> <!-- Documentation should meet character percentage --> <Rule Id="SA1631" Action="Warning"/> <!-- Documentation should meet character percentage -->
<Rule Id="SA1632" Action="Warning"/> <!-- Documentation text should meet minimum character length --> <Rule Id="SA1632" Action="Warning"/> <!-- Documentation text should meet minimum character length -->

View File

@ -1,6 +1,6 @@
var target = Argument("target", "Default"); var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release"); var configuration = Argument("configuration", "Release");
var pkgOutPath = $"./dist/NSExt/pkg/{configuration}"; var framework = Argument("framework", "net7.0");
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Tasks // Tasks
@ -8,123 +8,108 @@ var pkgOutPath = $"./dist/NSExt/pkg/{configuration}";
Task("Clean") Task("Clean")
.Does(context => .Does(context =>
{ {
context.CleanDirectory(pkgOutPath); context.CleanDirectory("./dist");
}); });
Task("Build") Task("Build")
.IsDependentOn("Clean") .IsDependentOn("Clean")
.Does(context => .Does(context =>
{ {
DotNetBuild("./NSExt.sln", new DotNetBuildSettings { DotNetPublish("./src/NSExt/NSExt.csproj", new DotNetPublishSettings {
Configuration = configuration, Configuration = configuration,
NoIncremental = context.HasArgument("rebuild"), Framework = framework,
MSBuildSettings = new DotNetMSBuildSettings()
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
}); });
}); });
Task("Test") // Task("Test")
.IsDependentOn("Build") // .IsDependentOn("Build")
.Does(context => // .Does(context =>
{ // {
DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings { // DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
Configuration = configuration, // Configuration = configuration,
NoRestore = true, // NoRestore = true,
NoBuild = true, // NoBuild = true,
}); // });
//
// DotNetTest("./test/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
// Configuration = configuration,
// NoRestore = true,
// NoBuild = true,
// });
//
// DotNetTest("./test/Spectre.Console.Analyzer.Tests/Spectre.Console.Analyzer.Tests.csproj", new DotNetTestSettings {
// Configuration = configuration,
// NoRestore = true,
// NoBuild = true,
// });
// });
DotNetTest("./test/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
Configuration = configuration,
NoRestore = true,
NoBuild = true,
});
DotNetTest("./test/Spectre.Console.Analyzer.Tests/Spectre.Console.Analyzer.Tests.csproj", new DotNetTestSettings { // Task("Publish-GitHub")
Configuration = configuration, // .WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
NoRestore = true, // //.IsDependentOn("Package")
NoBuild = true, // .Does(context =>
}); // {
}); // var apiKey = Argument<string>("github-key", null);
// if(string.IsNullOrWhiteSpace(apiKey)) {
Task("Package") // throw new CakeException("No GitHub API key was provided.");
.IsDependentOn("Build") // }
.Does(context => //
{ // // Publish to GitHub Packages
context.DotNetPack("./NSExt.sln", new DotNetPackSettings { // var exitCode = 0;
Configuration = configuration, // foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
NoRestore = true, // {
NoBuild = true, // context.Information("Publishing {0}...", file.GetFilename().FullPath);
OutputDirectory = pkgOutPath, // exitCode += StartProcess("dotnet",
MSBuildSettings = new DotNetMSBuildSettings() // new ProcessSettings {
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error) // Arguments = new ProcessArgumentBuilder()
}); // .Append("gpr")
}); // .Append("push")
// .AppendQuoted(file.FullPath)
Task("Publish-GitHub") // .AppendSwitchSecret("-k", " ", apiKey)
.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions") // }
.IsDependentOn("Package") // );
.Does(context => // }
{ //
var apiKey = Argument<string>("github-key", null); // if(exitCode != 0)
if(string.IsNullOrWhiteSpace(apiKey)) { // {
throw new CakeException("No GitHub API key was provided."); // throw new CakeException("Could not push GitHub packages.");
} // }
// });
// Publish to GitHub Packages
var exitCode = 0;
foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
{
context.Information("Publishing {0}...", file.GetFilename().FullPath);
exitCode += StartProcess("dotnet",
new ProcessSettings {
Arguments = new ProcessArgumentBuilder()
.Append("gpr")
.Append("push")
.AppendQuoted(file.FullPath)
.AppendSwitchSecret("-k", " ", apiKey)
}
);
}
if(exitCode != 0)
{
throw new CakeException("Could not push GitHub packages.");
}
});
Task("Publish-NuGet") Task("Publish-NuGet")
// .WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions") //.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
.IsDependentOn("Package") .IsDependentOn("Build")
.Does(context => .Does(context =>
{ {
var apiKey = Argument<string>("nuget-key", null); var apiKey = Argument<string>("nuget-key", null);
if(string.IsNullOrWhiteSpace(apiKey)) { if(string.IsNullOrWhiteSpace(apiKey)) {
throw new CakeException("No NuGet API key was provided."); throw new CakeException("No NuGet API key was provided.");
} }
// Publish to GitHub Packages // Publish to GitHub Packages
foreach(var file in context.GetFiles($"{pkgOutPath}/*.*nupkg")) foreach(var file in context.GetFiles("./dist/NSExt/bin/Release/*.*"))
{ {
context.Information("Publishing {0}...", file.GetFilename().FullPath); context.Information("Publishing {0}...", file.GetFilename().FullPath);
DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings
{ {
Source = "https://api.nuget.org/v3/index.json", Source = "https://api.nuget.org/v3/index.json",
ApiKey = apiKey, ApiKey = apiKey,
SkipDuplicate = true SkipDuplicate = true
}); });
} }
}); });
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Targets // Targets
Task("Publish") Task("Publish")
//.IsDependentOn("Publish-GitHub") // .IsDependentOn("Publish-GitHub")
.IsDependentOn("Publish-NuGet"); .IsDependentOn("Publish-NuGet");
Task("Default") Task("Default")
.IsDependentOn("Package"); .IsDependentOn("Build");
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Execution // Execution

View File

@ -1 +1,2 @@
git reset --hard | git clean -d -fx . git reset --hard
git clean -d -fx .

BIN
key.snk Normal file

Binary file not shown.

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,29 +0,0 @@
using System.Reflection;
using NSExt.Attributes;
namespace NSExt.Extensions;
/// <summary>
/// EnumExtensions
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// 获取枚举的description属性
/// </summary>
/// <param name="e">枚举对象</param>
/// <returns>description属性</returns>
public static string Desc(this Enum e)
{
var t = e.GetType();
var fi = t.GetField(Enum.GetName(t, e)!);
var descAttr = fi!.GetCustomAttribute<DescriptionAttribute>(true);
if (descAttr is null) {
return Enum.GetName(t, e);
}
var str = descAttr.Description;
var locAttr = fi!.GetCustomAttribute<LocalizationAttribute>(true);
return locAttr is null ? str : locAttr.ResourceClass.GetProperty(str)?.GetValue(default) as string ?? str;
}
}

View File

@ -1,27 +0,0 @@
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace NSExt.Extensions;
/// <summary>
/// JsonSerializerOptionsExtensions
/// </summary>
public static class JsonSerializerOptionsExtensions
{
/// <summary>
/// NewJsonSerializerOptions
/// </summary>
public static JsonSerializerOptions NewJsonSerializerOptions(this JsonSerializerOptions _)
{
return new JsonSerializerOptions {
ReadCommentHandling = JsonCommentHandling.Skip
, AllowTrailingCommas = true
, DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
, PropertyNamingPolicy = JsonNamingPolicy.CamelCase
, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
, NumberHandling = JsonNumberHandling.AllowReadingFromString
, PropertyNameCaseInsensitive = true
};
}
}

View File

@ -1,88 +0,0 @@
// ReSharper disable TemplateIsNotCompileTimeConstantProblem
namespace NSExt.Extensions;
/// <summary>
/// LoggerExtensions
/// </summary>
public static class LoggerExtensions
{
private const string _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER
= "{Message} <s:{ThreadId}#{CallerName}@{CallerFilePath}:{CallerLineNumber}>";
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logDebug
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Debug, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logError
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Error, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logFatal
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Critical, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logInfo
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Information, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logWarn
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Warning, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
/// <summary>
/// Debug
/// </summary>
public static void Debug(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logDebug(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture)
, null);
}
/// <summary>
/// Error
/// </summary>
public static void Error(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logError(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture)
, null);
}
/// <summary>
/// Fatal
/// </summary>
public static void Fatal(this ILogger me, object message, Exception ex = null
, [CallerMemberName] string callerName = null, [CallerFilePath] string callerFilePath = null
, [CallerLineNumber] int callerLineNumber = 0)
{
_logFatal(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture)
, ex);
}
/// <summary>
/// Info
/// </summary>
public static void Info(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logInfo(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture)
, null);
}
/// <summary>
/// Warn
/// </summary>
public static void Warn(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logWarn(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture)
, null);
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="xunit" Version="2.4.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NSExt\NSExt.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,41 @@
using NSExt.Attributes;
using NSExt.Extensions;
using Xunit;
using Xunit.Abstractions;
namespace NSExt.Tests;
/// <summary>
/// 测试用例
/// </summary>
public class TestCase
{
private readonly ITestOutputHelper _testOutputHelper;
public TestCase(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
public enum MyEnum1
{
[ResourceDescription<TestCase>(nameof(Description))]
Online = 1
, Offline = 2
}
public static string Description { get; set; } = "123";
/// <summary>
/// Case1
/// </summary>
[Fact]
public void Case1()
{
var test = MyEnum1.Online.ResDesc<TestCase>();
_testOutputHelper.WriteLine(test);
Assert.True(test is not null);
}
}

View File

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="MinVer" Version="4.3.0-beta.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<Import Project="../CodeQuality.props" />
</Project>

View File

@ -0,0 +1,26 @@
namespace NSExt.Attributes;
/// <summary>
/// 本地化资源描述特性
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)]
public class ResourceDescriptionAttribute<T> : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ResourceDescriptionAttribute{T}" /> class.
/// </summary>
public ResourceDescriptionAttribute(string resourceName)
{
ResourceName = resourceName;
}
/// <summary>
/// 资源名称
/// </summary>
public string ResourceName { get; set; }
/// <summary>
/// 资源对象
/// </summary>
public T ResourceObject { get; set; }
}

View File

@ -8,7 +8,7 @@ public static class ByteExtensions
/// <summary> /// <summary>
/// base64编码 /// base64编码
/// </summary> /// </summary>
/// <param name="me">待编码的字节数组</param> /// <param name="me">me</param>
/// <returns>编码后的base64字符串</returns> /// <returns>编码后的base64字符串</returns>
public static string Base64(this byte[] me) public static string Base64(this byte[] me)
{ {
@ -18,7 +18,7 @@ public static class ByteExtensions
/// <summary> /// <summary>
/// 将字节数组解码成字符串 /// 将字节数组解码成字符串
/// </summary> /// </summary>
/// <param name="me">字节数组</param> /// <param name="me">me</param>
/// <param name="e">字符串使用的编码方式</param> /// <param name="e">字符串使用的编码方式</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me, Encoding e) public static string HexDe(this byte[] me, Encoding e)
@ -29,7 +29,7 @@ public static class ByteExtensions
/// <summary> /// <summary>
/// 将字节数组解码成字符串 /// 将字节数组解码成字符串
/// </summary> /// </summary>
/// <param name="me">字节数组</param> /// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me) public static string HexDe(this byte[] me)
{ {
@ -43,8 +43,8 @@ public static class ByteExtensions
/// <param name="upperCase">是否大写</param> /// <param name="upperCase">是否大写</param>
/// <param name="splitShar">字节间分隔符</param> /// <param name="splitShar">字节间分隔符</param>
/// <param name="splitInterval">分隔符跳跃字节数</param> /// <param name="splitInterval">分隔符跳跃字节数</param>
public static string String(this IEnumerable<byte> me, bool upperCase = true, string splitShar = "" public static string Str(this IEnumerable<byte> me, bool upperCase = true, string splitShar = ""
, int splitInterval = 1) , int splitInterval = 1)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
var i = 0; var i = 0;

View File

@ -13,7 +13,7 @@ public static class DateTimeExtensions
/// <summary> /// <summary>
/// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前 /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前
/// </summary> /// </summary>
/// <param name="me">时间对象</param> /// <param name="me">me</param>
/// <returns>字符串</returns> /// <returns>字符串</returns>
public static string TimeAgo(this DateTime me) public static string TimeAgo(this DateTime me)
{ {
@ -26,7 +26,7 @@ public static class DateTimeExtensions
/// <summary> /// <summary>
/// 指定时间的世界协调时的unix时间戳形式 /// 指定时间的世界协调时的unix时间戳形式
/// </summary> /// </summary>
/// <param name="me">指定时间</param> /// <param name="me">me</param>
/// <returns>unix时间戳</returns> /// <returns>unix时间戳</returns>
public static long TimeUnixUtc(this DateTime me) public static long TimeUnixUtc(this DateTime me)
{ {

View File

@ -1,7 +1,7 @@
namespace NSExt.Extensions; namespace NSExt.Extensions;
/// <summary> /// <summary>
/// DbCommandExtensions /// DbCommandExtensions
/// </summary> /// </summary>
public static class DbCommandExtensions public static class DbCommandExtensions
{ {
@ -10,22 +10,21 @@ public static class DbCommandExtensions
/// </summary> /// </summary>
public static string ParameterFormat(this DbCommand me) public static string ParameterFormat(this DbCommand me)
{ {
//var aa = pars.ToDictionary(it => it.ParameterName, it => it.Value); // var aa = pars.ToDictionary(it => it.ParameterName, it => it.Value);
var sql = me.CommandText; var sql = me.CommandText;
//应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10 // 应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10
for (var i = me.Parameters.Count - 1; i >= 0; i--) { for (var i = me.Parameters.Count - 1; i >= 0; i--) {
#pragma warning disable IDE0072 #pragma warning disable IDE0072
sql = me.Parameters[i].DbType switch { sql = me.Parameters[i].DbType switch {
#pragma warning restore IDE0072 #pragma warning restore IDE0072
DbType.String or DbType.DateTime or DbType.Date or DbType.Time or DbType.DateTime2 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.DateTimeOffset or DbType.Guid or DbType.VarNumeric or DbType.AnsiStringFixedLength
or DbType.AnsiString or DbType.AnsiString or DbType.StringFixedLength => sql.Replace( //
or DbType.StringFixedLength => me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'")
sql.Replace(me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'") , DbType.Boolean => sql.Replace( //
, DbType.Boolean => sql.Replace(// me.Parameters[i].ParameterName
me.Parameters[i].ParameterName , Convert.ToBoolean(me.Parameters[i].Value, CultureInfo.InvariantCulture) ? "1" : "0")
, Convert.ToBoolean(me.Parameters[i].Value, CultureInfo.InvariantCulture) ? "1" : "0")
, _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString()) , _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString())
}; };
} }

View File

@ -8,7 +8,7 @@ public static class DecimalExtensions
/// <summary> /// <summary>
/// 四舍五入后的近似值 /// 四舍五入后的近似值
/// </summary> /// </summary>
/// <param name="me">数字</param> /// <param name="me">me</param>
/// <param name="place">小数点位数</param> /// <param name="place">小数点位数</param>
/// <returns>处理后的值</returns> /// <returns>处理后的值</returns>
public static decimal Round(this decimal me, int place) public static decimal Round(this decimal me, int place)

View File

@ -0,0 +1,61 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using NSExt.Attributes;
namespace NSExt.Extensions;
/// <summary>
/// EnumExtensions
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// 获取枚举的description属性
/// </summary>
/// <param name="e">枚举对象</param>
/// <returns>description属性</returns>
[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<DescriptionAttribute>(true);
if (descAttr is null) {
return Enum.GetName(typeOfEnum, e);
}
var str = descAttr.Description;
var locAttr = typeOfField!.GetCustomAttribute<LocalizationAttribute>(true);
return locAttr is null ? str : locAttr.ResourceClass.GetProperty(str)?.GetValue(default) as string ?? str;
}
/// <summary>
/// 通过类泛型类型获取特性
/// </summary>
public static T GetAttributeOfType<T>(this Enum me)
where T : Attribute
{
return me.GetType().GetMember(me.ToString()).First().GetCustomAttributes<T>(false).FirstOrDefault();
}
/// <summary>
/// 获取显示特性
/// </summary>
public static DisplayAttribute GetDisplay(this Enum me)
{
return me.GetAttributeOfType<DisplayAttribute>();
}
/// <summary>
/// 获取枚举的本地化资源描述
/// </summary>
public static string ResDesc<T>(this Enum e)
{
var typeOfEnum = e.GetType();
var typeOfField = typeOfEnum.GetField(Enum.GetName(typeOfEnum, e)!);
var resDescAttr = typeOfField!.GetCustomAttribute<ResourceDescriptionAttribute<T>>(true);
return resDescAttr is null
? Enum.GetName(typeOfEnum, e)
: typeof(T).GetProperty(resDescAttr.ResourceName)?.GetValue(default) as string;
}
}

View File

@ -17,7 +17,7 @@ public static class EnumerableExtensions
/// 判断对象是否为null或不存在子元素如果为集合对象 /// 判断对象是否为null或不存在子元素如果为集合对象
/// </summary> /// </summary>
/// <typeparam name="T">对象类型</typeparam> /// <typeparam name="T">对象类型</typeparam>
/// <param name="me">指定对象</param> /// <param name="me">me</param>
/// <returns>空则返回true</returns> /// <returns>空则返回true</returns>
public static bool NullOrEmpty<T>(this IEnumerable<T> me) public static bool NullOrEmpty<T>(this IEnumerable<T> me)
{ {

View File

@ -9,7 +9,7 @@ public static class GenericExtensions
/// 从指定的对象拷贝属性 /// 从指定的对象拷贝属性
/// </summary> /// </summary>
/// <typeparam name="T">对象类型</typeparam> /// <typeparam name="T">对象类型</typeparam>
/// <param name="me">拷贝目标</param> /// <param name="me">me</param>
/// <param name="copyObj">拷贝来源</param> /// <param name="copyObj">拷贝来源</param>
/// <param name="propNameList">需要处理的属性名</param> /// <param name="propNameList">需要处理的属性名</param>
/// <param name="isIncludeOrExclude">True包含false排除</param> /// <param name="isIncludeOrExclude">True包含false排除</param>

View File

@ -17,7 +17,7 @@ public static class IntExtensions
/// <summary> /// <summary>
/// 生成随机数 /// 生成随机数
/// </summary> /// </summary>
/// <param name="me">大于等于[0],小于[1]</param> /// <param name="me">me</param>
public static int Rand(this int[] me) public static int Rand(this int[] me)
{ {
return new Random(Guid.NewGuid().GetHashCode()).Next(me[0], me[1]); return new Random(Guid.NewGuid().GetHashCode()).Next(me[0], me[1]);

View File

@ -0,0 +1,83 @@
// ReSharper disable TemplateIsNotCompileTimeConstantProblem
namespace NSExt.Extensions;
/// <summary>
/// LoggerExtensions
/// </summary>
public static class LoggerExtensions
{
private const string _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER
= "{Message} <s:{CallerName}@{CallerFilePath}:{CallerLineNumber}>";
private static readonly Action<ILogger, string, string, string, string, Exception> _logDebug
= LoggerMessage.Define<string, string, string, string>(LogLevel.Debug, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logError
= LoggerMessage.Define<string, string, string, string>(LogLevel.Error, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logFatal
= LoggerMessage.Define<string, string, string, string>(LogLevel.Critical, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logInfo
= LoggerMessage.Define<string, string, string, string>(LogLevel.Information, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logWarn
= LoggerMessage.Define<string, string, string, string>(LogLevel.Warning, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
/// <summary>
/// Debug
/// </summary>
public static void Debug(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logDebug(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
/// <summary>
/// Error
/// </summary>
public static void Error(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logError(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
/// <summary>
/// Fatal
/// </summary>
public static void Fatal(this ILogger me, object message, Exception ex = null
, [CallerMemberName] string callerName = null, [CallerFilePath] string callerFilePath = null
, [CallerLineNumber] int callerLineNumber = 0)
{
_logFatal(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), ex);
}
/// <summary>
/// Info
/// </summary>
public static void Info(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logInfo(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
/// <summary>
/// Warn
/// </summary>
public static void Warn(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logWarn(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
}

View File

@ -10,20 +10,17 @@ public static class ObjectExtensions
/// <summary> /// <summary>
/// 将一个对象序列化成json文本 /// 将一个对象序列化成json文本
/// </summary> /// </summary>
/// <param name="me">指定对象</param> /// <param name="me">me</param>
/// <param name="format">是否格式化</param>
/// <returns>json文本</returns> /// <returns>json文本</returns>
public static string Json(this object me, bool format = false) public static string Json(this object me)
{ {
var defaultOptions = default(JsonSerializerOptions).NewJsonSerializerOptions(); return JsonSerializer.Serialize(me);
defaultOptions.WriteIndented = format;
return Json(me, defaultOptions);
} }
/// <summary> /// <summary>
/// 将一个对象序列化成json文本 /// 将一个对象序列化成json文本
/// </summary> /// </summary>
/// <param name="me">指定对象</param> /// <param name="me">me</param>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>json文本</returns> /// <returns>json文本</returns>
public static string Json(this object me, JsonSerializerOptions options) public static string Json(this object me, JsonSerializerOptions options)

View File

@ -11,15 +11,13 @@ namespace NSExt.Extensions;
/// <summary> /// <summary>
/// StringExtensions /// StringExtensions
/// </summary> /// </summary>
#pragma warning disable CodeLinesAnalyzer
public static class StringExtensions public static class StringExtensions
{ {
private static readonly JsonSerializerOptions _defaultJsonSerializerOptions
= default(JsonSerializerOptions).NewJsonSerializerOptions();
/// <summary> /// <summary>
/// aes加密 /// aes加密
/// </summary> /// </summary>
/// <param name="me">要加密的串</param> /// <param name="me">me</param>
/// <param name="key">密钥</param> /// <param name="key">密钥</param>
public static string Aes(this string me, string key) public static string Aes(this string me, string key)
{ {
@ -36,7 +34,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// aes解密 /// aes解密
/// </summary> /// </summary>
/// <param name="me">要加密的串</param> /// <param name="me">me</param>
/// <param name="key">密钥</param> /// <param name="key">密钥</param>
public static string AesDe(this string me, string key) public static string AesDe(this string me, string key)
{ {
@ -53,7 +51,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// base64编码 /// base64编码
/// </summary> /// </summary>
/// <param name="me">待base64编码的字符串</param> /// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param> /// <param name="e">字符串的编码方式</param>
/// <returns>编码后的base64字符串</returns> /// <returns>编码后的base64字符串</returns>
public static string Base64(this string me, Encoding e) public static string Base64(this string me, Encoding e)
@ -64,7 +62,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// base64解码 /// base64解码
/// </summary> /// </summary>
/// <param name="me">待解码的字符串</param> /// <param name="me">me</param>
/// <returns>解码后的原始字节数组</returns> /// <returns>解码后的原始字节数组</returns>
public static byte[] Base64De(this string me) public static byte[] Base64De(this string me)
{ {
@ -74,7 +72,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// base64解码 /// base64解码
/// </summary> /// </summary>
/// <param name="me">待解码的字符串</param> /// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param> /// <param name="e">字符串的编码方式</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string Base64De(this string me, Encoding e) public static string Base64De(this string me, Encoding e)
@ -103,7 +101,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">待转换字符串</param> /// <param name="me">me</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
public static DateTime DateTime(this string me) public static DateTime DateTime(this string me)
{ {
@ -113,7 +111,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">待转换字符串</param> /// <param name="me">me</param>
/// <param name="format">日期格式</param> /// <param name="format">日期格式</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExact(this string me, string format) public static DateTime DateTimeExact(this string me, string format)
@ -124,7 +122,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">待转换字符串</param> /// <param name="me">me</param>
/// <param name="format">日期格式</param> /// <param name="format">日期格式</param>
/// <param name="def">转换失败时返回的日期对象</param> /// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
@ -138,7 +136,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">待转换字符串</param> /// <param name="me">me</param>
/// <param name="def">转换失败时返回的日期对象</param> /// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
public static DateTime DateTimeTry(this string me, DateTime def) public static DateTime DateTimeTry(this string me, DateTime def)
@ -149,7 +147,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to decimal /// string to decimal
/// </summary> /// </summary>
/// <param name="me">string</param> /// <param name="me">me</param>
/// <returns>decimal</returns> /// <returns>decimal</returns>
public static decimal Dec(this string me) public static decimal Dec(this string me)
{ {
@ -159,7 +157,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 尝试将字符串转为decimal /// 尝试将字符串转为decimal
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param> /// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的decimal</returns> /// <returns>转换后的decimal</returns>
public static decimal DecTry(this string me, decimal def) public static decimal DecTry(this string me, decimal def)
@ -170,7 +168,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to double /// string to double
/// </summary> /// </summary>
/// <param name="me">string</param> /// <param name="me">me</param>
/// <returns>Int32</returns> /// <returns>Int32</returns>
public static double Double(this string me) public static double Double(this string me)
{ {
@ -198,7 +196,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to float /// string to float
/// </summary> /// </summary>
/// <param name="me">string</param> /// <param name="me">me</param>
/// <returns>Int32</returns> /// <returns>Int32</returns>
public static float Float(this string me) public static float Float(this string me)
{ {
@ -208,7 +206,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转为guid /// 将字符串转为guid
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
public static Guid Guid(this string me) public static Guid Guid(this string me)
{ {
return System.Guid.Parse(me); return System.Guid.Parse(me);
@ -217,7 +215,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成guid /// 将字符串转换成guid
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="def">转换失败的返回值</param> /// <param name="def">转换失败的返回值</param>
public static Guid Guid(this string me, Guid def) public static Guid Guid(this string me, Guid def)
{ {
@ -227,7 +225,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成字节数组形式 /// 将字符串转换成字节数组形式
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>字节数组</returns> /// <returns>字节数组</returns>
public static byte[] Hex(this string me, Encoding e) public static byte[] Hex(this string me, Encoding e)
@ -238,7 +236,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成字节数组形式 /// 将字符串转换成字节数组形式
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <returns>字节数组</returns> /// <returns>字节数组</returns>
public static byte[] Hex(this string me) public static byte[] Hex(this string me)
{ {
@ -272,7 +270,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 解码html编码 /// 解码html编码
/// </summary> /// </summary>
/// <param name="me">html编码后的字符串</param> /// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string HtmlDe(this string me) public static string HtmlDe(this string me)
{ {
@ -282,7 +280,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to Int32 /// string to Int32
/// </summary> /// </summary>
/// <param name="me">string</param> /// <param name="me">me</param>
/// <returns>Int32</returns> /// <returns>Int32</returns>
public static int Int32(this string me) public static int Int32(this string me)
{ {
@ -292,7 +290,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 尝试将字符串转为int32 /// 尝试将字符串转为int32
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param> /// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int32</returns> /// <returns>转换后的int32</returns>
public static int Int32Try(this string me, int def) public static int Int32Try(this string me, int def)
@ -303,7 +301,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to Int64 /// string to Int64
/// </summary> /// </summary>
/// <param name="me">string</param> /// <param name="me">me</param>
/// <returns>Int64</returns> /// <returns>Int64</returns>
public static long Int64(this string me) public static long Int64(this string me)
{ {
@ -313,7 +311,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 尝试将字符串转为int64 /// 尝试将字符串转为int64
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param> /// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int64</returns> /// <returns>转换后的int64</returns>
public static long Int64Try(this string me, long def) public static long Int64Try(this string me, long def)
@ -332,7 +330,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 是否base64字符串 /// 是否base64字符串
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
public static bool IsBase64String(this string me) public static bool IsBase64String(this string me)
{ {
// 一个合法的Base64有着以下特征 // 一个合法的Base64有着以下特征
@ -366,7 +364,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 对一个手机号进行掩码处理 /// 对一个手机号进行掩码处理
/// </summary> /// </summary>
/// <param name="me">手机号</param> /// <param name="me">me</param>
/// <returns>掩码后的手机号</returns> /// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me) public static string MaskMobile(this string me)
{ {
@ -376,7 +374,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 对一个字符串进行md5hash运算 /// 对一个字符串进行md5hash运算
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns> /// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Md5(this string me, Encoding e) public static string Md5(this string me, Encoding e)
@ -389,7 +387,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身 /// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身
/// </summary> /// </summary>
/// <param name="me">指定字符串</param> /// <param name="me">me</param>
/// <param name="defVal">指定的默认值</param> /// <param name="defVal">指定的默认值</param>
/// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns> /// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns>
public static string NullOrEmpty(this string me, string defVal) public static string NullOrEmpty(this string me, string defVal)
@ -408,30 +406,30 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 反序列化一个文件获得指定类型的数据对象 /// 反序列化一个文件获得指定类型的数据对象
/// </summary> /// </summary>
/// <param name="me">等待反序列化的json文本</param> /// <param name="me">me</param>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns> /// <returns>反序列化后生成的对象</returns>
public static T Object<T>(this string me, JsonSerializerOptions options = null) public static T Object<T>(this string me, JsonSerializerOptions options = null)
{ {
return JsonSerializer.Deserialize<T>(me, options ?? _defaultJsonSerializerOptions); return JsonSerializer.Deserialize<T>(me, options);
} }
/// <summary> /// <summary>
/// 反序列化一个文件获得指定类型的数据对象 /// 反序列化一个文件获得指定类型的数据对象
/// </summary> /// </summary>
/// <param name="me">等待反序列化的json文本</param> /// <param name="me">me</param>
/// <param name="type">实际类型</param> /// <param name="type">实际类型</param>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns> /// <returns>反序列化后生成的对象</returns>
public static object Object(this string me, Type type, JsonSerializerOptions options = null) public static object Object(this string me, Type type, JsonSerializerOptions options = null)
{ {
return JsonSerializer.Deserialize(me, type, options ?? _defaultJsonSerializerOptions); return JsonSerializer.Deserialize(me, type, options);
} }
/// <summary> /// <summary>
/// 生成密码 /// 生成密码
/// </summary> /// </summary>
/// <param name="me">密码原文</param> /// <param name="me">me</param>
/// <returns>密文</returns> /// <returns>密文</returns>
public static string Pwd(this string me) public static string Pwd(this string me)
{ {
@ -441,7 +439,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 移除字符串中的html标签 /// 移除字符串中的html标签
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <returns>处理之后的字符串</returns> /// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me) public static string RemoveHtmlTag(this string me)
{ {
@ -459,7 +457,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 对一个字符串进行sha1 hash运算 /// 对一个字符串进行sha1 hash运算
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns> /// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Sha1(this string me, Encoding e) public static string Sha1(this string me, Encoding e)
@ -497,6 +495,25 @@ public static class StringExtensions
return $"<pre>{me}</pre>"; return $"<pre>{me}</pre>";
} }
/// <summary>
/// 首字母小写
/// </summary>
public static string ToLowerCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me)
? me
: string.Concat( //
me[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(), me.AsSpan(1));
}
/// <summary>
/// 首字母大写
/// </summary>
public static string ToUpperCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me) ? me : string.Concat(me[0].ToString().ToUpperInvariant(), me.AsSpan(1));
}
/// <summary> /// <summary>
/// 将连续多个空格替换成一个空格 /// 将连续多个空格替换成一个空格
/// </summary> /// </summary>
@ -521,7 +538,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// url编码 /// url编码
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <returns>url编码后的字符串</returns> /// <returns>url编码后的字符串</returns>
public static string Url(this string me) public static string Url(this string me)
{ {
@ -531,7 +548,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 解码url编码 /// 解码url编码
/// </summary> /// </summary>
/// <param name="me">url编码后的字符串</param> /// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string UrlDe(this string me) public static string UrlDe(this string me)
{ {
@ -541,7 +558,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// MD5 hmac编码 /// MD5 hmac编码
/// </summary> /// </summary>
/// <param name="me">字符串</param> /// <param name="me">me</param>
/// <param name="key">密钥</param> /// <param name="key">密钥</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns> /// <returns>hash摘要的16进制文本形式无连字符小写</returns>
@ -553,3 +570,4 @@ public static class StringExtensions
.ToLower(CultureInfo.CurrentCulture); .ToLower(CultureInfo.CurrentCulture);
} }
} }
#pragma warning restore CodeLinesAnalyzer

35
src/NSExt/NSExt.csproj Normal file
View File

@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../CodeQuality.props" />
<PropertyGroup>
<AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Description>A .NET extension function library</Description>
<EmbedAllSources>true</EmbedAllSources>
<EmbedUntrackedSource>true</EmbedUntrackedSource>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeSymbols>true</IncludeSymbols>
<IsPackable>true</IsPackable>
<PackageIcon>logo.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/nsnail/ns-ext.git</PackageProjectUrl>
<PackageTags>extensions</PackageTags>
<Product>NSExt</Product>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/nsnail/ns-ext.git</RepositoryUrl>
<SignAssembly>true</SignAssembly>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Title>$(AssemblyName)</Title>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="MinVer" Version="4.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Include="../../logo.png" Pack="true" PackagePath="" />
</ItemGroup>
</Project>