This commit is contained in:
tk 2023-12-14 11:10:47 +08:00
parent 8c0dbcf1f4
commit 30d1a60a7b
50 changed files with 299 additions and 2105 deletions

View File

@ -15,28 +15,6 @@ indent_size = 2
[*.cs] [*.cs]
dotnet_analyzer_diagnostic.severity = warning dotnet_analyzer_diagnostic.severity = warning
dotnet_diagnostic.CA1200.severity = none
dotnet_diagnostic.CA1707.severity = none
dotnet_diagnostic.CA1716.severity = none
dotnet_diagnostic.IDE0005.severity = none
dotnet_diagnostic.IDE0008.severity = none
dotnet_diagnostic.IDE0010.severity = none
dotnet_diagnostic.IDE0055.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
# ReSharper properties # ReSharper properties
resharper_align_linq_query = true resharper_align_linq_query = true
@ -73,7 +51,6 @@ resharper_wrap_before_eq = true
resharper_wrap_chained_method_calls = chop_if_long resharper_wrap_chained_method_calls = chop_if_long
resharper_wrap_switch_expression = chop_if_long resharper_wrap_switch_expression = chop_if_long
# Microsoft .NET properties # Microsoft .NET properties
csharp_indent_braces = false csharp_indent_braces = false
csharp_new_line_before_open_brace = local_functions, methods, types csharp_new_line_before_open_brace = local_functions, methods, types

9
.gitignore vendored
View File

@ -55,7 +55,7 @@ nunit-*.xml
dlldata.c dlldata.c
# Benchmark Results # Benchmark Results
BenchmarkDotNet.Artifacts/ BenchmarkNSExtNet.Artifacts/
# .NET Core # .NET Core
project.lock.json project.lock.json
@ -130,12 +130,12 @@ $tf/
# ReSharper is a .NET coding add-in # ReSharper is a .NET coding add-in
_ReSharper*/ _ReSharper*/
*.[Rr]e[Ss]harper *.[Rr]e[Ss]harper
*.DotSettings.user *.NSExtSettings.user
# TeamCity is a build add-in # TeamCity is a build add-in
_TeamCity* _TeamCity*
# DotCover is a Code Coverage Tool # NSExtCover is a Code Coverage Tool
*.dotCover *.dotCover
# AxoCover is a Code Coverage Tool # AxoCover is a Code Coverage Tool
@ -400,6 +400,7 @@ FodyWeavers.xsd
# User Define # User Define
dist/ dist/
refs/
*.[Dd]esigner.cs *.[Dd]esigner.cs
*.db *.db
cache
/assets/res/Ln.resx

View File

@ -1,4 +0,0 @@
[hook "startcommit"]
cmdline = dot.clean.cmd
wait = true
show = true

View File

@ -1,26 +1,36 @@
<!-- 注意此文件名大小写不可变更 -->
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<!-- $(XXX) 定义有顺序 排序请注意-->
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir> <SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup>
<Import Project="$(SolutionDir)/build/minver.targets"/>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Authors>nsnail</Authors> <Authors>nsnail</Authors>
<BaseIntermediateOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath> <BaseIntermediateOutputPath>$(SolutionDir)/dist/backend/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath>
<BaseOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/bin</BaseOutputPath> <BaseOutputPath>$(SolutionDir)/dist/backend/$(MSBuildProjectName)/bin</BaseOutputPath>
<Copyright>© 2006-2023 nsnail</Copyright> <Copyright>© 2006-2023 nsnail</Copyright>
<Description>A .NET extension function library</Description> <Description>The NSExt is a .NET extension function library</Description>
<EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning> <EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<LangVersion>preview</LangVersion>
<MinVerDefaultPreReleaseIdentifiers>beta</MinVerDefaultPreReleaseIdentifiers> <MinVerDefaultPreReleaseIdentifiers>beta</MinVerDefaultPreReleaseIdentifiers>
<MinVerTagPrefix>v</MinVerTagPrefix>
<NoWarn>CA1707;IDE0005;IDE0008;IDE0010;IDE0028;IDE0055;IDE0160;IDE0300;IDE0305;RCS1141;RCS1142;RCS1181;S101;S1121;S1135;S125;S2094;S3604;S4663;SYSLIB1045;SA1010;RCS1123;SA1407;IDE0048;S1075;S3928</NoWarn>
<Product>NSExt</Product> <Product>NSExt</Product>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/nsnail/NSExt.git</RepositoryUrl> <RepositoryUrl>https://github.com/nsnail/NSExt.git</RepositoryUrl>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks> <TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<Title>$(AssemblyName)</Title> <Title>$(AssemblyName)</Title>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MinVer" Version="5.0.0-alpha.1"> <PackageReference Include="MinVer" Version="5.0.0-beta.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Include="../GlobalUsings.cs" Link="GlobalUsings.cs"/>
</ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 nsnail Copyright (c) 2023 nsnail
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -3,38 +3,66 @@ 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("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C84EB5A0-37AD-4B17-A51E-E36888C4441E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "backend", "backend", "{4DAF9366-855F-46BB-AE4C-660C92FA0697}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0CAC-4828-A807-34A693F73859}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0CAC-4828-A807-34A693F73859}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.commitlintrc.js = .commitlintrc.js
.editorconfig = .editorconfig .editorconfig = .editorconfig
.gitattributes = .gitattributes .gitattributes = .gitattributes
.gitignore = .gitignore .gitignore = .gitignore
.tgitconfig = .tgitconfig CHANGELOG.md = CHANGELOG.md
build.cake = build.cake
code.cleanup.full.ps1 = code.cleanup.full.ps1
code.quality.props = code.quality.props
Directory.Build.props = Directory.Build.props Directory.Build.props = Directory.Build.props
dot.clean.cmd = dot.clean.cmd
dotnet-tools.json = dotnet-tools.json dotnet-tools.json = dotnet-tools.json
git.pr.ps1 = git.pr.ps1
git.rc.ps1 = git.rc.ps1
global.json = global.json global.json = global.json
image.optimize.csx = image.optimize.csx
key.snk = key.snk
LICENSE = LICENSE LICENSE = LICENSE
logo.png = logo.png
NSExt.sln.DotSettings = NSExt.sln.DotSettings NSExt.sln.DotSettings = NSExt.sln.DotSettings
nuget.config = nuget.config NuGet.Config = NuGet.Config
packable.props = packable.props package.json = package.json
README.md = README.md README.md = README.md
README.zh-CN.md = README.zh-CN.md README.zh-CN.md = README.zh-CN.md
stylecop.analyzers.ruleset = stylecop.analyzers.ruleset
stylecop.json = stylecop.json
sync.metafiles.csx = sync.metafiles.csx
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt.Tests", "src\NSExt.Tests\NSExt.Tests.csproj", "{557FBEF6-E6D5-4531-86DF-D772A10E2261}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B25C9-0901-4923-913F-00F9A6B352A5}"
ProjectSection(SolutionItems) = preProject
clean.ln.csx = scripts/clean.ln.csx
code.clean.csx = scripts/code.clean.csx
code.clean.ps1 = scripts/code.clean.ps1
gen.cs.tt = scripts/gen.cs.tt
gen.ln.cmd = scripts/gen.ln.cmd
gen.resx.tt = scripts/gen.resx.tt
git.pr.ps1 = scripts/git.pr.ps1
git.rc.ps1 = scripts/git.rc.ps1
image.optimize.csx = scripts/image.optimize.csx
install.as.tpl.ps1 = scripts/install.as.tpl.ps1
rename.csx = scripts/rename.csx
resharper.full.ps1 = scripts/resharper.full.ps1
switcher.nsext.json = scripts/switcher.nsext.json
switcher.ps1 = scripts/switcher.ps1
sync.sln.files.csx = scripts/sync.sln.files.csx
EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt\NSExt.csproj", "{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1129FE25-466B-4F4F-85FC-3752664245E1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{3C6F049E-3EE8-4D66-9AFF-E8A369032487}"
ProjectSection(SolutionItems) = preProject
ci.yml = .github/workflows/ci.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8E4C93BA-9493-4892-80C4-5E174C504829}"
ProjectSection(SolutionItems) = preProject
code.quality.props = build/code.quality.props
copy.pkg.xml.comment.files.targets = build/copy.pkg.xml.comment.files.targets
minver.targets = build/minver.targets
prebuild.targets = build/prebuild.targets
stylecop.analyzers.ruleset = build/stylecop.analyzers.ruleset
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\backend\NSExt\NSExt.csproj", "{1E62C322-EE42-4699-A6F1-791C53EFA62D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt.Tests", "src\backend\NSExt.Tests\NSExt.Tests.csproj", "{00604162-C444-478B-B773-3AB23C856CA7}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -45,13 +73,19 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1E62C322-EE42-4699-A6F1-791C53EFA62D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E62C322-EE42-4699-A6F1-791C53EFA62D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E62C322-EE42-4699-A6F1-791C53EFA62D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.Build.0 = Release|Any CPU {1E62C322-EE42-4699-A6F1-791C53EFA62D}.Release|Any CPU.Build.0 = Release|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {00604162-C444-478B-B773-3AB23C856CA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.Build.0 = Debug|Any CPU {00604162-C444-478B-B773-3AB23C856CA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.ActiveCfg = Release|Any CPU {00604162-C444-478B-B773-3AB23C856CA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.Build.0 = Release|Any CPU {00604162-C444-478B-B773-3AB23C856CA7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4DAF9366-855F-46BB-AE4C-660C92FA0697} = {C84EB5A0-37AD-4B17-A51E-E36888C4441E}
{3C6F049E-3EE8-4D66-9AFF-E8A369032487} = {1129FE25-466B-4F4F-85FC-3752664245E1}
{1E62C322-EE42-4699-A6F1-791C53EFA62D} = {4DAF9366-855F-46BB-AE4C-660C92FA0697}
{00604162-C444-478B-B773-3AB23C856CA7} = {4DAF9366-855F-46BB-AE4C-660C92FA0697}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,34 +1,57 @@
<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/CodeEditing/GenerateMemberBody/DocumentationGenerationKind/@EntryValue">Inherit</s:String> <s:String x:Key="/Default/CodeEditing/GenerateMemberBody/DocumentationGenerationKind/@EntryValue">Inherit</s:String>
<s:Boolean x:Key="/Default/CodeEditing/TypingAssist/SkipClosingBracesOnTabInStringLiterals/@EntryValue">True</s:Boolean> <s:Boolean
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignmentInConditionalExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String> x:Key="/Default/CodeEditing/TypingAssist/SkipClosingBracesOnTabInStringLiterals/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:Boolean
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String> x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Ett/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> <s:String
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignmentInConditionalExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LocalizableElement/@EntryIndexedValue">HINT</s:String>
<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_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> <s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IOS/@EntryIndexedValue">IOS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IOS/@EntryIndexedValue">IOS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String> <s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">True</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>
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">OFF</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">OFF</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">HINT</s:String> <s:String
x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String> <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String> <s:String
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String> x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String> <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@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/=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;
@ -80,7 +103,6 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Haojia/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Haojia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=hongbao/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=hongbao/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=inte/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=inte/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lant/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=logourl/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=logourl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Meituan/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Meituan/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=miaosha/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=miaosha/@EntryIndexedValue">True</s:Boolean>

131
README.md
View File

@ -1,65 +1,96 @@
# ns-ext # dot
[](README.zh-CN.md) | **En** [](README.zh-CN.md) | **En**
The **ns-ext** is a .NET extension function library, containing the following types of extension modules:
| Features | File name | Cross-platform, all-around utility set with a beautiful character interface-the Swiss Army knife
|------------------------------------------|------------------------------------|
| 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 |
## Quick start ### Brief introduction
### Install The dot is the one based on the one. NET 7, a cross-platform command-line tool, integrates more than 10 utilities that
program developers often use in their daily work, and is constantly increasing.
```
USAGE:
dot [OPTIONS] <COMMAND>
OPTIONS:
-h, --help Prints help information
-v, --version Prints version information
COMMANDS:
git Git batch operation tool
color Screen coordinate color selection tool
tran Translation tools
guid GUID tool
ip IP tools
json Json tool
pwd <password length> <generate type> Random password generator
rbom Remove the uf8 bom of the file
trim Remove line breaks and spaces at the end of the file
text Text encoding tool
time Time synchronization tool
tolf Convert newline characters to LF
get <url> Multithreaded download tool
```shell
dotnet add package NSExt --prerelease
``` ```
### Example ### Some functional examples
```c# - ##### Git batch management
using NSExt.Extensions;
internal static class Program When you have a clone and a lot of git repositories, use this command to pull their latest code all at once:
{
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<Person>();
Console.WriteLine(person.Json()); ```
} dot git -a "pull" d:\repos
}
``` ```
### Output ![20221212212417](./assets/snapshots/20221212212417.png)
Similarly, you can execute any git commands on a bunch of git repositories in bulk:
```json
{"name":"Jason","age":30}
``` ```
dot git -a "config --get http.proxy" d:\repos
```
![20221212213957](./assets/snapshots/20221212213957.png)
- ##### High-precision time-clock synchronization
Supports parallel requests from multiple NTP clock servers, while removing the network communication duration to set the
precise synchronization of the native clocks with the NTP standard time:
```
dot time -k
```
![20221212214514](./assets/snapshots/20221212214514.png)
- ##### Text codec
Copy you need to view various codec text in the clipboard, and then enter the following command to view
```
dot text
```
![20221212214904](./assets/snapshots/20221212214904.png)
- ##### Multi-threading download tool
Support setting the block size, number of threads to replace the single thread wget tool:
```
dot get https://github.com/nsnail/dot/releases/download/v1.1.1/dot-v1.1.1-win-x64.7z
```
![20221212215259](./assets/snapshots/20221212215259.png)
- ##### Remove the blank at the end of the file
Remove excess spaces and line breaks in the tail of all files in the specified directory:
```
dot trim d:\repos
```
![20221212215853](./assets/snapshots/20221212215853.png)

View File

@ -1,65 +1,94 @@
# ns-ext # dot
[En](README.md) | **中** [En](README.md) | **中**
**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 |
## 快速开始 dot 是一款基于.NET7跨平台的命令行工具集成10多种程序开发人员在日常工作常常用到的实用功能并且还在不断增加。
### 安装 ```
USAGE:
dot [OPTIONS] <COMMAND>
OPTIONS:
-h, --help Prints help information
-v, --version Prints version information
COMMANDS:
git Git批量操作工具
color 屏幕坐标颜色选取工具
tran 翻译工具
guid GUID工具
ip IP工具
json Json工具
pwd <password length> <generate type> 随机密码生成器
rbom 移除文件的uf8 bom
trim 移除文件尾部换行和空格
text 文本编码工具
time 时间同步工具
tolf 转换换行符为LF
get <url> 多线程下载工具
```shell
dotnet add package NSExt --prerelease
``` ```
### 示例 ### 部分功能示例
```c# - ##### Git批量管理
using NSExt.Extensions;
internal static class Program 当你clone了大量的git仓库 使用这条命令可以一次性拉取它们的最新代码:
{
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<Person>();
Console.WriteLine(person.Json()); ```
} dot git -a "pull" d:\repos
}
``` ```
### 输出 ![20221212212417](./assets/snapshots/20221212212417.png)
类似地你可以批量对一堆git仓库执行任何git命令
```json
{"name":"Jason","age":30}
``` ```
dot git -a "config --get http.proxy" d:\repos
```
![20221212213957](./assets/snapshots/20221212213957.png)
- ##### 高精度时钟同步
支持多个NTP时钟服务器并行请求同时除去网络通信时长以设置本机时钟与NTP标准时间精确同步
```
dot time -k
```
![20221212214514](./assets/snapshots/20221212214514.png)
- ##### 文本编解码
复制你需要查看各种编解码的文本在剪贴板中,然后输入如下命令,即可查看
```
dot text
```
![20221212214904](./assets/snapshots/20221212214904.png)
- ##### 多线程下载工具
支持设置分块大小线程数量用以替代单线程的wget工具
```
dot get https://github.com/nsnail/dot/releases/download/v1.1.1/dot-v1.1.1-win-x64.7z
```
![20221212215259](./assets/snapshots/20221212215259.png)
- ##### 移除文件末尾空白
移除指定目录下所有文件尾部多余的空格和换行符:
```
dot trim d:\repos
```
![20221212215853](./assets/snapshots/20221212215853.png)

View File

@ -1,117 +0,0 @@
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var framework = Argument("framework", "net7.0");
////////////////////////////////////////////////////////////////
// Tasks
Task("Clean")
.Does(context =>
{
context.CleanDirectory("./dist");
});
Task("Build")
.IsDependentOn("Clean")
.Does(context =>
{
DotNetPublish("./src/NSExt/NSExt.csproj", new DotNetPublishSettings {
Configuration = configuration,
Framework = framework,
});
});
// Task("Test")
// .IsDependentOn("Build")
// .Does(context =>
// {
// DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.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 {
// Configuration = configuration,
// NoRestore = true,
// NoBuild = true,
// });
// });
// Task("Publish-GitHub")
// .WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
// //.IsDependentOn("Package")
// .Does(context =>
// {
// var apiKey = Argument<string>("github-key", null);
// if(string.IsNullOrWhiteSpace(apiKey)) {
// throw new CakeException("No GitHub API key was provided.");
// }
//
// // 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")
//.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
.IsDependentOn("Build")
.Does(context =>
{
var apiKey = Argument<string>("nuget-key", null);
if(string.IsNullOrWhiteSpace(apiKey)) {
throw new CakeException("No NuGet API key was provided.");
}
// Publish to GitHub Packages
foreach(var file in context.GetFiles("./dist/NSExt/bin/Release/*.*"))
{
context.Information("Publishing {0}...", file.GetFilename().FullPath);
DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings
{
Source = "https://api.nuget.org/v3/index.json",
ApiKey = apiKey,
SkipDuplicate = true
});
}
});
////////////////////////////////////////////////////////////////
// Targets
Task("Publish")
// .IsDependentOn("Publish-GitHub")
.IsDependentOn("Publish-NuGet");
Task("Default")
.IsDependentOn("Build");
////////////////////////////////////////////////////////////////
// Execution
RunTarget(target)

View File

@ -1 +0,0 @@
dotnet jb cleanupcode --no-build ./NSExt.sln

View File

@ -1,43 +0,0 @@
<Project>
<PropertyGroup>
<CodeAnalysisRuleSet>$(SolutionDir)/stylecop.analyzers.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
<MSBuildWarningsAsErrors>true</MSBuildWarningsAsErrors>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors>true</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.507">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.11.0.78383">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="AsyncSuffixAnalyzer" Version="1.0.6285.32977">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="AsyncFixer" Version="1.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ProductiveRage.SealedClassVerification.Net" Version="1.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- <PackageReference Include="NSCodeAnalysis" Version="1.0.1-alpha.0.2">-->
<!-- <PrivateAssets>all</PrivateAssets>-->
<!-- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
<!-- </PackageReference>-->
</ItemGroup>
</Project>

View File

@ -1,3 +0,0 @@
dot rbom -w -e refs -e .git -e node_modules
dot trim -w -e refs -e .git -e node_modules
dot tolf -w -e refs -e .git -e node_modules

View File

@ -2,23 +2,29 @@
"version": 1, "version": 1,
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"cake.tool": { "dotnet-t4": {
"version": "3.1.0", "version": "2.3.1",
"commands": [ "commands": [
"dotnet-cake" "t4"
] ]
}, },
"dotnet-script": { "dotnet-script": {
"version": "1.4.0", "version": "1.5.0",
"commands": [ "commands": [
"dotnet-script" "dotnet-script"
] ]
}, },
"jetbrains.resharper.globaltools": { "jetbrains.resharper.globaltools": {
"version": "2023.2.0", "version": "2023.3.0",
"commands": [ "commands": [
"jb" "jb"
] ]
},
"dnt": {
"version": "1.8.3",
"commands": [
"dnt"
]
} }
} }
} }

View File

@ -1,26 +0,0 @@
$types = @{
'1' = @('FEA', '新增特性')
'2' = @('REF', '项目重构')
'3' = @('FIX', '缺陷修复')
'4' = @('PER', '性能优化')
'5' = @('RVT', '还原变更')
'6' = @('FMT', '格式整理')
'7' = @('DOC', '文档变更')
'8' = @('TST', '单元测试')
'9' = @('BLD', '工程构建')
}
git add ./
$prefix = ''
while ($null -eq $types[$prefix])
{
$prefix = Read-Host "请选择提交类型`n" $( & { param($i) $i | ForEach-Object { "$_ : $( $types[$_][0] )$( $types[$_][1] )`n" } } $types.Keys | Sort-Object )
}
git commit -m "[$($types[$prefix][0])] $(($(Read-Host '是否跳过自动构建Y/n') -eq 'n') ? '': '[SKIP CI] ')$(Read-Host '请输入提交消息')"
$branch = $(git branch --show-current)
& './dot.clean.cmd'
git add ./
git commit --amend --no-edit
git pull
git push --set-upstream origin $branch
Start-Process -FilePath "https://github.com/nsnail/NSExt/compare/main...$branch"
Pause

View File

@ -1,6 +0,0 @@
$branch = $(git branch --show-current)
git checkout main
git pull
git branch -D $branch
git branch $branch
git checkout $branch

View File

@ -1,10 +1,10 @@
{ {
"sdk": { "sdk": {
"version": "7.0.0", "version": "8.0.0",
"rollForward": "latestMajor", "rollForward": "latestMajor",
"allowPrerelease": true "allowPrerelease": true
}, },
"tools": { "tools": {
"dotnet": "7.0.0" "dotnet": "8.0.0"
} }
} }

View File

@ -1,65 +0,0 @@
/*
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}");
}
);

BIN
key.snk

Binary file not shown.

BIN
logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,18 +0,0 @@
<Project>
<PropertyGroup>
<AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<EmbedAllSources>true</EmbedAllSources>
<EmbedUntrackedSource>true</EmbedUntrackedSource>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeSymbols>true</IncludeSymbols>
<IsPackable>true</IsPackable>
<PackageIcon>logo.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/nsnail/NSExt.git</PackageProjectUrl>
<PackageTags>extensions</PackageTags>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<SignAssembly>true</SignAssembly>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
</Project>

View File

@ -1,6 +0,0 @@
Remove-Item ./dist -Recurse -Force -Confirm:$false
dotnet build -c Release
$apikey = Read-Host -Prompt "nuget apikey"
foreach ($file in Get-ChildItem -Path ./dist/NSExt/bin/Release | Where-Object { $_.Name -match "nupkg" }) {
dotnet nuget push $file --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
}

View File

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0-preview-23424-02"/>
<PackageReference Include="xunit" Version="2.5.2-pre.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NSExt\NSExt.csproj"/>
</ItemGroup>
</Project>

View File

@ -1,36 +0,0 @@
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,26 +0,0 @@
namespace NSExt.Attributes;
/// <summary>
/// 指定本地化资源类型
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)]
public sealed class LocalizationAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="LocalizationAttribute" /> class.
/// </summary>
#pragma warning disable IDE0290
public LocalizationAttribute(Type resourceClass)
#pragma warning restore IDE0290
{
ResourceClass = resourceClass;
}
/// <summary>
/// Gets or sets 资源类型
/// </summary>
/// <value>
/// 资源类型
/// </value>
public Type ResourceClass { get; set; }
}

View File

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

View File

@ -1,21 +0,0 @@
namespace NSExt.Constant;
#pragma warning disable SYSLIB1045
/// <summary>
/// 使用 RegexGenerator 新特性会生成重复key值的xmlComment导致出错
/// </summary>
internal static class Regexes
{
public static readonly Regex RegexBacksLantUnicode
= new(@"\\u([a-fA-F0-9]{4})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex RegexHtmlTag = new("<[^>]*>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex RegexMobile
= new(@"^(\d{3})\d{4}(\d{4})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex RegexPercentUnicode
= new(@"\\u([a-fA-F0-9]{4})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex RegexUpLetter = new("([A-Z])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
}

View File

@ -1,61 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// ByteExtensions
/// </summary>
public static class ByteExtensions
{
/// <summary>
/// base64编码
/// </summary>
/// <param name="me">me</param>
/// <returns>编码后的base64字符串</returns>
public static string Base64(this byte[] me)
{
return Convert.ToBase64String(me);
}
/// <summary>
/// 将字节数组解码成字符串
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码方式</param>
/// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me, Encoding e)
{
return e.GetString(me);
}
/// <summary>
/// 将字节数组解码成字符串
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me)
{
return me.HexDe(Encoding.UTF8);
}
/// <summary>
/// 将字节数组转换成16进制字符串
/// </summary>
/// <param name="me">me</param>
/// <param name="upperCase">是否大写</param>
/// <param name="splitShar">字节间分隔符</param>
/// <param name="splitInterval">分隔符跳跃字节数</param>
public static string Str(this IEnumerable<byte> me, bool upperCase = true, string splitShar = ""
, int splitInterval = 1)
{
var sb = new StringBuilder();
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(c);
}
return sb.ToString();
}
}

View File

@ -1,23 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// CharExtensions
/// </summary>
public static class CharExtensions
{
/// <summary>
/// 是否数字或大小写字母
/// </summary>
public static bool IsAsciiLetterOrDigit(this char me)
{
return (((uint)me - 'A') & ~0x20) < 26 || (uint)me - '0' < 10;
}
/// <summary>
/// 是否base64字符
/// </summary>
public static bool IsBase64Character(this char me)
{
return IsAsciiLetterOrDigit(me) || me is '+' or '/' or '=';
}
}

View File

@ -1,110 +0,0 @@
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
#pragma warning disable SA1300, IDE1006
namespace NSExt.Extensions;
/// <summary>
/// DateTimeExtensions
/// </summary>
public static class DateTimeExtensions
{
/// <summary>
/// 指定时间的世界协调时的unix时间戳形式
/// </summary>
/// <param name="me">me</param>
/// <returns>unix时间戳</returns>
public static long TimeUnixUtc(this DateTime me)
{
return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
/// <summary>
/// 指定时间的世界协调时的unix时间戳形式毫秒
/// </summary>
public static long TimeUnixUtcMs(this DateTime me)
{
return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000;
}
/// <summary>
/// ToString 的 Invariant 版本
/// </summary>
public static string ToInvString(this DateTime me)
{
return me.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前
/// </summary>
/// <param name="me">me</param>
/// <returns>字符串</returns>
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 + "秒前" }
}
};
}
/// <summary>
/// yyyy_MM
/// </summary>
public static string yyyy_MM(this DateTime me)
{
return me.ToString("yyyy-MM", CultureInfo.InvariantCulture);
}
/// <summary>
/// yyyy_MM_dd
/// </summary>
public static string yyyy_MM_dd(this DateTime me)
{
return me.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
/// <summary>
/// yyyy_MM_dd_HH_mm
/// </summary>
public static string yyyy_MM_dd_HH_mm(this DateTime me)
{
return me.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
}
/// <summary>
/// yyyy_MM_dd_HH_mm_ss
/// </summary>
public static string yyyy_MM_dd_HH_mm_ss(this DateTime me)
{
return me.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
}
/// <summary>
/// yyyy_MM_dd_HH_mm_ss_fff
/// </summary>
public static string yyyy_MM_dd_HH_mm_ss_fff(this DateTime me)
{
return me.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
}
/// <summary>
/// yyyyMM
/// </summary>
public static string yyyyMM(this DateTime me)
{
return me.ToString("yyyyMM", CultureInfo.InvariantCulture);
}
/// <summary>
/// yyyyMMdd
/// </summary>
public static string yyyyMMdd(this DateTime me)
{
return me.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
}
}

View File

@ -1,36 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// DbCommandExtensions
/// </summary>
public static class DbCommandExtensions
{
/// <summary>
/// 格式化参数拼接成完整的SQL语句
/// </summary>
public static string ParameterFormat(this DbCommand me)
{
var sql = me.CommandText;
// 应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10
for (var i = me.Parameters.Count - 1; i >= 0; i--) {
#pragma warning disable IDE0072
sql = me.Parameters[i].DbType switch {
#pragma warning restore IDE0072
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
, 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())
};
}
return sql;
}
}

View File

@ -1,26 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// DecimalExtensions
/// </summary>
public static class DecimalExtensions
{
/// <summary>
/// 四舍五入后的近似值
/// </summary>
/// <param name="me">me</param>
/// <param name="place">小数点位数</param>
/// <returns>处理后的值</returns>
public static decimal Round(this decimal me, int place)
{
return Math.Round(me, place);
}
/// <summary>
/// ToString 的 Invariant 版本
/// </summary>
public static string ToInvString(this decimal me)
{
return me.ToString(CultureInfo.InvariantCulture);
}
}

View File

@ -1,41 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using NSExt.Attributes;
namespace NSExt.Extensions;
/// <summary>
/// EnumExtensions
/// </summary>
public static class EnumExtensions
{
/// <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;
}
/// <summary>
/// 通过类泛型类型获取特性
/// </summary>
private static T GetAttributeOfType<T>(this Enum me)
where T : Attribute
{
return me.GetType().GetMember(me.ToString())[0].GetCustomAttributes<T>(false).FirstOrDefault();
}
}

View File

@ -1,26 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// EnumerableExtensions
/// </summary>
public static class EnumerableExtensions
{
/// <summary>
/// 将列表转成分隔符分隔的字符串
/// </summary>
public static string Join(this IEnumerable<object> me, string separator)
{
return string.Join(separator, me);
}
/// <summary>
/// 判断对象是否为null或不存在子元素如果为集合对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="me">me</param>
/// <returns>空则返回true</returns>
public static bool NullOrEmpty<T>(this IEnumerable<T> me)
{
return me?.Any() != true;
}
}

View File

@ -1,41 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// GenericExtensions
/// </summary>
public static class GenericExtensions
{
/// <summary>
/// 从指定的对象拷贝属性
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="me">me</param>
/// <param name="copyObj">拷贝来源</param>
/// <param name="propNameList">需要处理的属性名</param>
/// <param name="isIncludeOrExclude">True包含false排除</param>
public static void CopyFrom<T>(this T me, T copyObj, IList<string> propNameList = null
, bool isIncludeOrExclude = false)
{
foreach (var p in me.GetType().GetProperties()) {
if (!p.CanWrite) {
continue;
}
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);
}
}
}
/// <summary>
/// 判断是否与某对象相等
/// </summary>
public static T Is<T>(this T me, T compare, T ret)
where T : struct
{
return me.Equals(compare) ? ret : me;
}
}

View File

@ -1,41 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// IntExtensions
/// </summary>
public static class IntExtensions
{
/// <summary>
/// 判断枚举是否包含某个位
/// </summary>
public static bool HasFlag<T>(this int me, T flag)
where T : Enum
{
return ((long)me).HasFlag(flag);
}
/// <summary>
/// 生成随机数
/// </summary>
/// <param name="me">me</param>
public static int Rand(this int[] me)
{
return new Random(Guid.NewGuid().GetHashCode()).Next(me[0], me[1]);
}
/// <summary>
/// ToString 的 Invariant 版本
/// </summary>
public static string ToInvString(this int me)
{
return me.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// 转换成ipv4
/// </summary>
public static string ToIpV4(this int me)
{
return string.Join(".", BitConverter.GetBytes(me).Reverse());
}
}

View File

@ -1,83 +0,0 @@
// ReSharper disable TemplateIsNotCompileTimeConstantProblem
namespace NSExt.Extensions;
/// <summary>
/// LoggerExtensions
/// </summary>
public static class LoggerExtensions
{
private const string _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER
= "{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_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logError
= LoggerMessage.Define<string, string, string, string>(LogLevel.Error, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logFatal
= LoggerMessage.Define<string, string, string, string>(LogLevel.Critical, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logInfo
= LoggerMessage.Define<string, string, string, string>(LogLevel.Information, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logWarn
= LoggerMessage.Define<string, string, string, string>(LogLevel.Warning, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
/// <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

@ -1,42 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// LongExtensions
/// </summary>
public static class LongExtensions
{
/// <summary>
/// 判断枚举是否包含某个位
/// </summary>
public static bool HasFlag<T>(this long me, T flag)
where T : Enum
{
var val = (long)(object)flag;
return (me & val) == val;
}
/// <summary>
/// 生成随机数
/// </summary>
/// <param name="me">me</param>
public static long Rand(this long[] me)
{
return new Random(Guid.NewGuid().GetHashCode()).NextInt64(me[0], me[1]);
}
/// <summary>
/// 1970毫秒数转换成日期对象
/// </summary>
public static DateTime Time(this long msFrom1970)
{
return DateTime.UnixEpoch.AddMilliseconds(msFrom1970).ToLocalTime();
}
/// <summary>
/// ToString 的 Invariant 版本
/// </summary>
public static string ToInvString(this long me)
{
return me.ToString(CultureInfo.InvariantCulture);
}
}

View File

@ -1,30 +0,0 @@
using System.Text.Json;
namespace NSExt.Extensions;
/// <summary>
/// ObjectExtensions
/// </summary>
public static class ObjectExtensions
{
/// <summary>
/// 将一个对象序列化成json文本
/// </summary>
/// <param name="me">me</param>
/// <returns>json文本</returns>
public static string Json(this object me)
{
return JsonSerializer.Serialize(me);
}
/// <summary>
/// 将一个对象序列化成json文本
/// </summary>
/// <param name="me">me</param>
/// <param name="options">序列化选项</param>
/// <returns>json文本</returns>
public static string Json(this object me, JsonSerializerOptions options)
{
return JsonSerializer.Serialize(me, options);
}
}

View File

@ -1,32 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// StreamExtensions
/// </summary>
public static class StreamExtensions
{
/// <summary>
/// FirstByteIndex
/// </summary>
public static long FirstByteIndex(this Stream me, byte[] findBytes)
{
int data;
while ((data = me.ReadByte()) != -1) {
if (findBytes.Contains((byte)data)) {
return me.Position;
}
}
return -1;
}
/// <summary>
/// IsTextStream
/// </summary>
public static bool IsTextStream(this Stream me)
{
#pragma warning disable IDE0300
return me.FirstByteIndex(new byte[] { 0x00, 0xff }) < 0;
#pragma warning restore IDE0300
}
}

View File

@ -1,591 +0,0 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
#pragma warning disable CA1720
using System.Security.Cryptography;
using System.Text.Json;
using NSExt.Constant;
namespace NSExt.Extensions;
/// <summary>
/// StringExtensions
/// </summary>
#pragma warning disable CodeLinesAnalyzer
public static class StringExtensions
{
/// <summary>
/// aes加密
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
public static string Aes(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
aes.Key = key.Hex();
using var encryptor = aes.CreateEncryptor();
var bytes = me.Hex();
var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.Base64();
}
/// <summary>
/// aes解密
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
public static string AesDe(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
aes.Key = key.Hex();
using var encryptor = aes.CreateDecryptor();
var bytes = me.Base64De();
var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.HexDe();
}
/// <summary>
/// base64编码
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param>
/// <returns>编码后的base64字符串</returns>
public static string Base64(this string me, Encoding e)
{
return e.GetBytes(me).Base64();
}
/// <summary>
/// base64解码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字节数组</returns>
public static byte[] Base64De(this string me)
{
return Convert.FromBase64String(me);
}
/// <summary>
/// base64解码
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param>
/// <returns>解码后的原始字符串</returns>
public static string Base64De(this string me, Encoding e)
{
return e.GetString(me.Base64De());
}
/// <summary>
/// 将易于web传输的base64web字符串转换为原生base64
/// </summary>
/// <returns>原生base64</returns>
public static string Base64Sys(this string me)
{
return me.Replace("-", "+").Replace("_", "/").Replace(".", "=");
}
/// <summary>
/// 将原生base64字符串转换成易于web传输的字符串
/// </summary>
/// <returns>易于web传输的字符串</returns>
public static string Base64Web(this string me)
{
return me.Replace("+", "-").Replace("/", "_").Replace("=", ".");
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTime(this string me)
{
return System.DateTime.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="format">日期格式</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExact(this string me, string format)
{
return System.DateTime.ParseExact(me, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="format">日期格式</param>
/// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExactTry(this string me, string format, DateTime def)
{
return !System.DateTime.TryParseExact(me, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out var ret)
? def
: ret;
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeTry(this string me, DateTime def)
{
return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, out var ret) ? def : ret;
}
/// <summary>
/// string to decimal
/// </summary>
/// <param name="me">me</param>
/// <returns>decimal</returns>
public static decimal Dec(this string me)
{
return decimal.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为decimal
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的decimal</returns>
public static decimal DecTry(this string me, decimal def)
{
return !decimal.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to double
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static double Double(this string me)
{
return double.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
public static T Enum<T>(this string name)
where T : Enum
{
return (T)System.Enum.Parse(typeof(T), name, true);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
public static T EnumTry<T>(this string name, T def)
where T : Enum
{
return !System.Enum.TryParse(typeof(T), name, out var ret) ? def : (T)ret;
}
/// <summary>
/// string to float
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static float Float(this string me)
{
return float.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转为guid
/// </summary>
/// <param name="me">me</param>
public static Guid Guid(this string me)
{
return System.Guid.Parse(me);
}
/// <summary>
/// 将字符串转换成guid
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败的返回值</param>
public static Guid Guid(this string me, Guid def)
{
return System.Guid.TryParse(me, out var ret) ? ret : def;
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>字节数组</returns>
public static byte[] Hex(this string me, Encoding e)
{
return e.GetBytes(me);
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
/// <param name="me">me</param>
/// <returns>字节数组</returns>
public static byte[] Hex(this string me)
{
return me.Hex(Encoding.UTF8);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="secret">密钥</param>
/// <param name="e">使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
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)
.ToLower(CultureInfo.CurrentCulture);
}
/// <summary>
/// html编码
/// </summary>
public static string Html(this string me)
{
return HttpUtility.HtmlEncode(me);
}
/// <summary>
/// 解码html编码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string HtmlDe(this string me)
{
return HttpUtility.HtmlDecode(me);
}
/// <summary>
/// string to Int32
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static int Int32(this string me)
{
return int.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为int32
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int32</returns>
public static int Int32Try(this string me, int def)
{
return !int.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to Int64
/// </summary>
/// <param name="me">me</param>
/// <returns>Int64</returns>
public static long Int64(this string me)
{
return long.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为int64
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int64</returns>
public static long Int64Try(this string me, long def)
{
return !long.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// ipv4格式转int32格式
/// </summary>
public static int IpV4ToInt32(this string me)
{
return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0);
}
/// <summary>
/// 是否base64字符串
/// </summary>
/// <param name="me">me</param>
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;
}
var firstEqualSignPos = me.IndexOf('=');
if (firstEqualSignPos < 0) {
return true;
}
var lastEqualSignPos = me.LastIndexOf('=');
return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '=');
}
/// <summary>
/// 中文姓名打马赛克
/// </summary>
public static string MaskChineseName(this string me)
{
return me.Length == 2 ? "*" + me[1..] : me[..1] + "*" + me[^1..];
}
/// <summary>
/// 对一个手机号进行掩码处理
/// </summary>
/// <param name="me">me</param>
/// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me)
{
return Regexes.RegexMobile.Replace(me, "$1****$2");
}
/// <summary>
/// 对一个字符串进行md5hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
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);
}
/// <summary>
/// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身
/// </summary>
/// <param name="me">me</param>
/// <param name="defVal">指定的默认值</param>
/// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns>
public static string NullOrEmpty(this string me, string defVal)
{
return me.AsEnumerable().NullOrEmpty() ? defVal : me;
}
/// <summary>
/// null或空白字符
/// </summary>
public static bool NullOrWhiteSpace(this string me)
{
return string.IsNullOrWhiteSpace(me);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
/// <param name="me">me</param>
/// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns>
public static T Object<T>(this string me, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize<T>(me, options);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
/// <param name="me">me</param>
/// <param name="type">实际类型</param>
/// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns>
public static object Object(this string me, Type type, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize(me, type, options);
}
/// <summary>
/// 生成密码
/// </summary>
/// <param name="me">me</param>
/// <returns>密文</returns>
public static string Pwd(this string me)
{
return me.Md5Hmac(me.Md5(Encoding.UTF8), Encoding.UTF8);
}
/// <summary>
/// 移除字符串中的html标签
/// </summary>
/// <param name="me">me</param>
/// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me)
{
return Regexes.RegexHtmlTag.Replace(me, string.Empty);
}
/// <summary>
/// 删除换行符
/// </summary>
public static string RemoveWrapped(this string me)
{
return me.Replace("\r", string.Empty).Replace("\n", string.Empty);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
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);
}
/// <summary>
/// 蛇形命名
/// </summary>
public static string SnakeCase(this string me)
{
return Regexes.RegexUpLetter.Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
}
/// <summary>
/// 截取指定长度的字符串代替substring
/// </summary>
public static string Sub(this string me, int startIndex, int length)
{
if (startIndex + length > me.Length) {
length = me.Length - startIndex;
}
return me.Substring(startIndex, length);
}
/// <summary>
/// 纯文本字符串转html
/// </summary>
public static string Text2Html(this string me)
{
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>
public static string TrimSpaces(this string me)
{
var ret = me.Replace(" ", " ");
// ReSharper disable once TailRecursiveCall
return ret == me ? ret : ret.TrimSpaces();
}
/// <summary>
/// 将\ux0000 、 %u0000 、 &amp;#x0000; 编码转换成可读字符串
/// </summary>
public static string UnicodeDe(this string me)
{
const string replacement = "&#x$1;";
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();
}
/// <summary>
/// url编码
/// </summary>
/// <param name="me">me</param>
/// <returns>url编码后的字符串</returns>
public static string Url(this string me)
{
return Uri.EscapeDataString(me);
}
/// <summary>
/// 解码url编码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string UrlDe(this string me)
{
return Uri.UnescapeDataString(me);
}
/// <summary>
/// MD5 hmac编码
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
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);
}
}
#pragma warning restore CodeLinesAnalyzer

View File

@ -1,19 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// TypeExtensions
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。
/// </summary>
public static IEnumerable<T> GetCustomAttributesIncludingBaseInterfaces<T>(this Type me)
{
var attributeType = typeof(T);
return me.GetCustomAttributes(attributeType, true)
.Union(me.GetInterfaces()
.SelectMany(interfaceType => interfaceType.GetCustomAttributes(attributeType, true)))
.Cast<T>();
}
}

View File

@ -1,15 +0,0 @@
namespace NSExt.Extensions;
/// <summary>
/// UriExtensions
/// </summary>
public static class UriExtensions
{
/// <summary>
/// 移除url的Scheme
/// </summary>
public static string RemoveScheme(this Uri me)
{
return "//" + me.Authority + me.PathAndQuery;
}
}

View File

@ -1,8 +0,0 @@
global using System.Data;
global using System.Data.Common;
global using System.Globalization;
global using System.Runtime.CompilerServices;
global using System.Text;
global using System.Text.RegularExpressions;
global using System.Web;
global using Microsoft.Extensions.Logging;

View File

@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../code.quality.props"/>
<Import Project="../../packable.props"/>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0"/>
</ItemGroup>
<ItemGroup>
<None Include="../../logo.png" Pack="true" PackagePath=""/>
</ItemGroup>
</Project>

View File

View File

@ -1,243 +0,0 @@
<?xml version="1.0"?>
<RuleSet Name="StyleCop.Analyzers rules with default action"
Description="StyleCop.Analyzers with default action. Rules with IsEnabledByDefault = false are disabled."
ToolsVersion="14.0">
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.SpecialRules">
<Rule Id="SA0001" Action="Warning"/> <!-- XML comment analysis disabled -->
<Rule Id="SA0002" Action="Warning"/> <!-- Invalid settings file -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.SpacingRules">
<Rule Id="SA1000" Action="Warning"/> <!-- Keywords should be spaced correctly -->
<Rule Id="SA1001" Action="None"/> <!-- Commas 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="SA1004" Action="Warning"/> <!-- Documentation lines 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="SA1007" Action="Warning"/> <!-- Operator keyword should be followed by space -->
<Rule Id="SA1008" Action="None"/> <!-- Opening parenthesis should be spaced correctly -->
<Rule Id="SA1009" Action="Warning"/> <!-- Closing parenthesis should be spaced correctly -->
<Rule Id="SA1010" Action="Warning"/> <!-- Opening square brackets should be spaced correctly -->
<Rule Id="SA1011" Action="Warning"/> <!-- Closing square brackets should be spaced correctly -->
<Rule Id="SA1012" Action="Warning"/> <!-- Opening braces should be spaced correctly -->
<Rule Id="SA1013" Action="Warning"/> <!-- Closing braces should be spaced correctly -->
<Rule Id="SA1014" Action="Warning"/> <!-- Opening generic brackets should be spaced correctly -->
<Rule Id="SA1015" Action="Warning"/> <!-- Closing generic brackets should be spaced correctly -->
<Rule Id="SA1016" Action="Warning"/> <!-- Opening attribute brackets should be spaced correctly -->
<Rule Id="SA1017" Action="Warning"/> <!-- Closing attribute brackets should be spaced correctly -->
<Rule Id="SA1018" Action="Warning"/> <!-- Nullable type symbols should be spaced correctly -->
<Rule Id="SA1019" Action="Warning"/> <!-- Member access symbols should be spaced correctly -->
<Rule Id="SA1020" Action="Warning"/> <!-- Increment decrement symbols should be spaced correctly -->
<Rule Id="SA1021" Action="Warning"/> <!-- Negative signs should be spaced correctly -->
<Rule Id="SA1022" Action="Warning"/> <!-- Positive signs should be spaced correctly -->
<Rule Id="SA1023"
Action="Warning"/> <!-- Dereference and access of symbols should be spaced correctly -->
<Rule Id="SA1024" Action="Warning"/> <!-- Colons should be spaced correctly -->
<Rule Id="SA1025" Action="None"/> <!-- Code should not contain multiple whitespace in a row -->
<Rule Id="SA1026"
Action="Warning"/> <!-- Code should not contain space after new or stackalloc keyword in implicitly typed array allocation -->
<Rule Id="SA1027" Action="Warning"/> <!-- Use tabs correctly -->
<Rule Id="SA1028" Action="Warning"/> <!-- Code should not contain trailing whitespace -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.ReadabilityRules">
<Rule Id="SA1100"
Action="Warning"/> <!-- Do not prefix calls with base unless local implementation exists -->
<Rule Id="SA1101" Action="None"/> <!-- Prefix local calls with this -->
<Rule Id="SA1102" Action="Warning"/> <!-- Query clause should follow previous clause -->
<Rule Id="SA1103"
Action="Warning"/> <!-- Query clauses should be on separate lines or all on one line -->
<Rule Id="SA1104"
Action="Warning"/> <!-- Query clause should begin on new line when previous clause spans multiple lines -->
<Rule Id="SA1105"
Action="Warning"/> <!-- Query clauses spanning multiple lines should begin on own line -->
<Rule Id="SA1106" Action="Warning"/> <!-- Code should not contain empty statements -->
<Rule Id="SA1107" Action="Warning"/> <!-- Code should not contain multiple statements on one line -->
<Rule Id="SA1108" Action="Warning"/> <!-- Block statements should not contain embedded comments -->
<Rule Id="SA1109" Action="Warning"/> <!-- Block statements should not contain embedded regions -->
<Rule Id="SA1110"
Action="Warning"/> <!-- Opening parenthesis or bracket should be on declaration line -->
<Rule Id="SA1111" Action="Warning"/> <!-- Closing parenthesis should be on line of last parameter -->
<Rule Id="SA1112"
Action="Warning"/> <!-- Closing parenthesis should be on line of opening parenthesis -->
<Rule Id="SA1113" Action="None"/> <!-- Comma should be on the same line as previous parameter -->
<Rule Id="SA1114" Action="Warning"/> <!-- Parameter list should follow declaration -->
<Rule Id="SA1115" Action="Warning"/> <!-- Parameter should follow comma -->
<Rule Id="SA1116" Action="Warning"/> <!-- Split parameters should start on line after declaration -->
<Rule Id="SA1117" Action="None"/> <!-- Parameters should be on same line or separate lines -->
<Rule Id="SA1118" Action="None"/> <!-- Parameter should not span multiple lines -->
<Rule Id="SA1120" Action="None"/> <!-- Comments should contain text -->
<Rule Id="SA1121" Action="Warning"/> <!-- Use built-in type alias -->
<Rule Id="SA1122" Action="Warning"/> <!-- Use string.Empty for empty strings -->
<Rule Id="SA1123" Action="Warning"/> <!-- Do not place regions within elements -->
<Rule Id="SA1124" Action="Warning"/> <!-- Do not use regions -->
<Rule Id="SA1125" Action="Warning"/> <!-- Use shorthand for nullable types -->
<Rule Id="SA1126" Action="Warning"/> <!-- Prefix calls correctly -->
<Rule Id="SA1127" Action="Warning"/> <!-- Generic type constraints should be on their own line -->
<Rule Id="SA1128" Action="Warning"/> <!-- Put constructor initializers on their own line -->
<Rule Id="SA1129" Action="Warning"/> <!-- Do not use default value type constructor -->
<Rule Id="SA1130" Action="Warning"/> <!-- Use lambda syntax -->
<Rule Id="SA1131" Action="Warning"/> <!-- Use readable conditions -->
<Rule Id="SA1132" Action="Warning"/> <!-- Do not combine fields -->
<Rule Id="SA1133" Action="Warning"/> <!-- Do not combine attributes -->
<Rule Id="SA1134" Action="Warning"/> <!-- Attributes should not share line -->
<Rule Id="SA1135" Action="Warning"/> <!-- Using directives should be qualified -->
<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="SA1139" Action="Warning"/> <!-- Use literal suffix notation instead of casting -->
<Rule Id="SX1101" Action="Warning"/> <!-- Do not prefix local calls with 'this.' -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.OrderingRules">
<Rule Id="SA1200" Action="None"/> <!-- Using directives should be placed correctly -->
<Rule Id="SA1201" Action="Warning"/> <!-- Elements should appear in the correct order -->
<Rule Id="SA1202" Action="Warning"/> <!-- Elements should be ordered by access -->
<Rule Id="SA1203" Action="Warning"/> <!-- Constants should appear before fields -->
<Rule Id="SA1204" Action="Warning"/> <!-- Static elements should appear before instance elements -->
<Rule Id="SA1205" Action="Warning"/> <!-- Partial elements should declare access -->
<Rule Id="SA1206" Action="Warning"/> <!-- Declaration keywords should follow order -->
<Rule Id="SA1207" Action="Warning"/> <!-- Protected should come before internal -->
<Rule Id="SA1208"
Action="Warning"/> <!-- System using directives should be placed before other using directives -->
<Rule Id="SA1209"
Action="Warning"/> <!-- Using alias directives should be placed after other using directives -->
<Rule Id="SA1210"
Action="Warning"/> <!-- Using directives should be ordered alphabetically by namespace -->
<Rule Id="SA1211"
Action="Warning"/> <!-- Using alias directives should be ordered alphabetically by alias name -->
<Rule Id="SA1212" Action="Warning"/> <!-- Property accessors should follow order -->
<Rule Id="SA1213" Action="Warning"/> <!-- Event accessors should follow order -->
<Rule Id="SA1214" Action="Warning"/> <!-- Readonly fields should appear before non-readonly fields -->
<Rule Id="SA1216"
Action="Warning"/> <!-- Using static directives should be placed at the correct location -->
<Rule Id="SA1217" Action="Warning"/> <!-- Using static directives should be ordered alphabetically -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.NamingRules">
<Rule Id="SA1300" Action="Warning"/> <!-- Element should begin with upper-case letter -->
<Rule Id="SA1301" Action="Warning"/> <!-- Element should begin with lower-case letter -->
<Rule Id="SA1302" Action="Warning"/> <!-- Interface names should begin with I -->
<Rule Id="SA1303" Action="Warning"/> <!-- Const field names should begin with upper-case letter -->
<Rule Id="SA1304"
Action="Warning"/> <!-- Non-private readonly fields should begin with upper-case letter -->
<Rule Id="SA1305" Action="None"/> <!-- Field names should not use Hungarian notation -->
<Rule Id="SA1306" Action="Warning"/> <!-- Field names should begin with lower-case letter -->
<Rule Id="SA1307" Action="Warning"/> <!-- Accessible fields should begin with upper-case letter -->
<Rule Id="SA1308" Action="Warning"/> <!-- Variable names should not be prefixed -->
<Rule Id="SA1309" Action="None"/> <!-- Field names should not begin with 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="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="SA1314" Action="Warning"/> <!-- Type parameter names should begin with T -->
<Rule Id="SX1309" Action="Warning"/> <!-- Field names should begin with underscore -->
<Rule Id="SX1309S" Action="Warning"/> <!-- Static field names should begin with underscore -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.MaintainabilityRules">
<Rule Id="SA1119" Action="Warning"/> <!-- Statement should not use unnecessary parenthesis -->
<Rule Id="SA1400" Action="Warning"/> <!-- Access modifier should be declared -->
<Rule Id="SA1401" Action="Warning"/> <!-- Fields should be private -->
<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="SA1404" Action="Warning"/> <!-- Code analysis suppression should have justification -->
<Rule Id="SA1405" Action="Warning"/> <!-- Debug.Assert should provide message text -->
<Rule Id="SA1406" Action="Warning"/> <!-- Debug.Fail should provide message text -->
<Rule Id="SA1407" Action="Warning"/> <!-- Arithmetic expressions should declare precedence -->
<Rule Id="SA1408" Action="Warning"/> <!-- Conditional expressions should declare precedence -->
<Rule Id="SA1409" Action="Warning"/> <!-- Remove unnecessary code -->
<Rule Id="SA1410" Action="Warning"/> <!-- Remove delegate parenthesis when possible -->
<Rule Id="SA1411"
Action="Warning"/> <!-- Attribute constructor should not use unnecessary parenthesis -->
<Rule Id="SA1412" Action="None"/> <!-- Store files as UTF-8 with byte order mark -->
<Rule Id="SA1413" Action="None"/> <!-- Use trailing comma in multi-line initializers -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.LayoutRules">
<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="SA1502" Action="None"/> <!-- Element should not be on a single line -->
<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="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="SA1507" Action="Warning"/> <!-- Code should not contain multiple blank lines in a row -->
<Rule Id="SA1508" Action="Warning"/> <!-- Closing braces should not be preceded by blank line -->
<Rule Id="SA1509" Action="Warning"/> <!-- Opening braces should not be preceded by blank line -->
<Rule Id="SA1510"
Action="Warning"/> <!-- Chained statement blocks should not be preceded by blank line -->
<Rule Id="SA1511" Action="Warning"/> <!-- While-do footer should not be preceded by blank line -->
<Rule Id="SA1512" Action="Warning"/> <!-- Single-line comments should not be followed by blank line -->
<Rule Id="SA1513" Action="Warning"/> <!-- Closing brace should be followed by blank line -->
<Rule Id="SA1514"
Action="Warning"/> <!-- Element documentation header should be preceded by blank line -->
<Rule Id="SA1515" Action="Warning"/> <!-- Single-line comment should be preceded by blank line -->
<Rule Id="SA1516" Action="Warning"/> <!-- Elements should be separated by blank line -->
<Rule Id="SA1517" Action="Warning"/> <!-- Code should not contain blank lines at start of file -->
<Rule Id="SA1518" Action="Warning"/> <!-- Use line endings correctly at end of file -->
<Rule Id="SA1519"
Action="Warning"/> <!-- Braces should not be omitted from multi-line child statement -->
<Rule Id="SA1520" Action="Warning"/> <!-- Use braces consistently -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers.DocumentationRules">
<Rule Id="SA1600" Action="None"/> <!-- Elements should be documented -->
<Rule Id="SA1601" Action="None"/> <!-- Partial elements should be documented -->
<Rule Id="SA1602" Action="None"/> <!-- Enumeration items should be documented -->
<Rule Id="SA1603" Action="Warning"/> <!-- Documentation should contain valid XML -->
<Rule Id="SA1604" Action="Warning"/> <!-- Element documentation should have summary -->
<Rule Id="SA1605" Action="Warning"/> <!-- Partial element documentation should have summary -->
<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="SA1608" Action="Warning"/> <!-- Element documentation should not have default summary -->
<Rule Id="SA1609" Action="None"/> <!-- Property documentation should have value -->
<Rule Id="SA1610" Action="Warning"/> <!-- Property documentation should have value text -->
<Rule Id="SA1611" Action="None"/> <!-- Element parameters should be documented -->
<Rule Id="SA1612"
Action="Warning"/> <!-- Element parameter documentation should match element parameters -->
<Rule Id="SA1613"
Action="Warning"/> <!-- Element parameter documentation should declare parameter name -->
<Rule Id="SA1614" Action="Warning"/> <!-- Element parameter documentation should have text -->
<Rule Id="SA1615" Action="None"/> <!-- Element return value should be documented -->
<Rule Id="SA1616" Action="Warning"/> <!-- Element return value documentation should have text -->
<Rule Id="SA1617" Action="Warning"/> <!-- Void return value should not be documented -->
<Rule Id="SA1618" Action="None"/> <!-- Generic type parameters should be documented -->
<Rule Id="SA1619"
Action="None"/> <!-- Generic type parameters should be documented partial class -->
<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="SA1622" Action="Warning"/> <!-- Generic type parameter documentation should have text -->
<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="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="SA1627" Action="Warning"/> <!-- Documentation text should not be empty -->
<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="SA1630" Action="Warning"/> <!-- Documentation text should contain whitespace -->
<Rule Id="SA1631" Action="Warning"/> <!-- Documentation should meet character percentage -->
<Rule Id="SA1632" Action="Warning"/> <!-- Documentation text should meet minimum character length -->
<Rule Id="SA1633" Action="None"/> <!-- File should have header -->
<Rule Id="SA1634" Action="Warning"/> <!-- File header should show copyright -->
<Rule Id="SA1635" Action="Warning"/> <!-- File header should have copyright text -->
<Rule Id="SA1636" Action="Warning"/> <!-- File header copyright text should match -->
<Rule Id="SA1637" Action="Warning"/> <!-- File header should contain file name -->
<Rule Id="SA1638"
Action="Warning"/> <!-- File header file name documentation should match file name -->
<Rule Id="SA1639" Action="Warning"/> <!-- File header should have summary -->
<Rule Id="SA1640" Action="Warning"/> <!-- File header should have valid company text -->
<Rule Id="SA1641" Action="Warning"/> <!-- File header company name text should match -->
<Rule Id="SA1642"
Action="Warning"/> <!-- Constructor summary documentation should begin with standard text -->
<Rule Id="SA1643"
Action="Warning"/> <!-- Destructor summary documentation should begin with standard text -->
<Rule Id="SA1644" Action="Warning"/> <!-- Documentation headers should not contain blank lines -->
<Rule Id="SA1645" Action="Warning"/> <!-- Included documentation file does not exist -->
<Rule Id="SA1646" Action="Warning"/> <!-- Included documentation XPath does not exist -->
<Rule Id="SA1647" Action="Warning"/> <!-- Include node does not contain valid file and path -->
<Rule Id="SA1648" Action="Warning"/> <!-- Inheritdoc should be used with inheriting class -->
<Rule Id="SA1649" Action="Warning"/> <!-- File name should match first type name -->
<Rule Id="SA1650" Action="Warning"/> <!-- Element documentation should be spelled correctly -->
<Rule Id="SA1651" Action="Warning"/> <!-- Do not use placeholder elements -->
</Rules>
</RuleSet>

View File

@ -1,9 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"indentation": {
"useTabs": false,
"indentationSize": 4
}
}
}

View File

@ -1,20 +0,0 @@
using System.Text.RegularExpressions;
var slnFile = Directory.GetFiles(@"./", "*.sln").First();
var content = File.ReadAllText(slnFile);
content = Regex.Replace(
content,
"Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"meta\", \"meta\", \"{5198A03D-0CAC-4828-A807-34A693F73859}\"(?:.|\n)*?EndProject",
$$"""
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0CAC-4828-A807-34A693F73859}"
{{'\t'}}ProjectSection(SolutionItems) = preProject
{{string.Join('\n',
Directory.GetFiles(@"./", "*").Where(x => !x.EndsWith(".sln") && !x.EndsWith(".user"))
.Select(x=>$"\t\t{Path.GetFileName(x)} = {Path.GetFileName(x)}")
)}}
{{'\t'}}EndProject
"""
);
Console.WriteLine(content);
File.WriteAllText(slnFile, content);