5 Commits
1.1.0 ... 1.0.8

Author SHA1 Message Date
cb63791dbc <chore> 2022-12-13 16:10:50 +08:00
3a1a71d1c1 <adjust> 2022-12-09 16:55:52 +08:00
54082a82f1 1.0.8 2022-12-09 11:27:39 +08:00
1ea481e749 1.0.7 2022-12-09 11:24:01 +08:00
d9aae8fe95 <chore> 2022-12-04 22:22:35 +08:00
63 changed files with 726 additions and 1591 deletions

View File

@ -1,42 +1,12 @@
root = true root = true
[*] [*]
charset = utf-8
end_of_line = lf
ij_xml_attribute_wrap = off
ij_xml_text_wrap = off
indent_size = 4
indent_style = space indent_style = space
insert_final_newline = false indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
[{*.json,*.yml}]
indent_size = 2
[*.cs]
dotnet_analyzer_diagnostic.severity = warning
dotnet_diagnostic.CA1200.severity = none
dotnet_diagnostic.CA1707.severity = none
dotnet_diagnostic.CA1716.severity = none
dotnet_diagnostic.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
@ -53,27 +23,23 @@ resharper_align_multline_type_parameter_constrains = true
resharper_align_multline_type_parameter_list = true resharper_align_multline_type_parameter_list = true
resharper_align_tuple_components = true resharper_align_tuple_components = true
resharper_allow_comment_after_lbrace = true resharper_allow_comment_after_lbrace = true
resharper_blank_lines_before_single_line_comment = 1
resharper_csharp_empty_block_style = together_same_line resharper_csharp_empty_block_style = together_same_line
resharper_csharp_outdent_commas = true resharper_csharp_outdent_commas = true
resharper_csharp_place_type_constraints_on_same_line = false
resharper_csharp_stick_comment = false resharper_csharp_stick_comment = false
resharper_csharp_wrap_before_comma = true resharper_csharp_wrap_before_comma = true
resharper_indent_nested_for_stmt = true
resharper_indent_nested_foreach_stmt = true resharper_indent_nested_foreach_stmt = true
resharper_indent_nested_for_stmt = true
resharper_indent_nested_while_stmt = true resharper_indent_nested_while_stmt = true
resharper_indent_preprocessor_if = usual_indent resharper_indent_preprocessor_if = usual_indent
resharper_indent_preprocessor_other = usual_indent resharper_indent_preprocessor_other = usual_indent
resharper_int_align = true resharper_int_align = true
resharper_keep_existing_arrangement = false resharper_keep_existing_arrangement = false
resharper_place_linq_into_on_new_line = false resharper_place_linq_into_on_new_line = false
resharper_place_simple_embedded_statement_on_same_line = false
resharper_place_simple_switch_expression_on_single_line = true resharper_place_simple_switch_expression_on_single_line = true
resharper_wrap_before_eq = true 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

7
.gitignore vendored
View File

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

View File

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

View File

@ -1,26 +1,20 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<!-- $(XXX) 定义有顺序 排序请注意-->
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
<Authors>nsnail</Authors>
<BaseIntermediateOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath>
<BaseOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/bin</BaseOutputPath>
<Copyright>© 2006-2023 nsnail</Copyright>
<Description>A .NET extension function library</Description>
<EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<MinVerDefaultPreReleaseIdentifiers>beta</MinVerDefaultPreReleaseIdentifiers> <BaseOutputPath>../build/$(MSBuildProjectName)/bin</BaseOutputPath>
<BaseIntermediateOutputPath>../build/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath>
<MSBuildProjectExtensionsPath>$(BaseIntermediateOutputPath)</MSBuildProjectExtensionsPath>
<Authors>nsnail</Authors>
<Product>NSExt</Product> <Product>NSExt</Product>
<RepositoryType>git</RepositoryType> <Copyright>© 2006-2022 nsnail</Copyright>
<RepositoryUrl>https://github.com/nsnail/NSExt.git</RepositoryUrl> <RepositoryUrl>https://github.com/nsnail/ns-ext.git</RepositoryUrl>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks> <PublishRepositoryUrl>true</PublishRepositoryUrl>
<Title>$(AssemblyName)</Title> <EmbedUntrackedSource>true</EmbedUntrackedSource>
<EmbedAllSources>true</EmbedAllSources>
<RepositoryType>Git</RepositoryType>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/nsnail/ns-ext.git</PackageProjectUrl>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="MinVer" Version="5.0.0-alpha.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

View File

@ -3,39 +3,27 @@ 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}") = "meta", "meta", "{5198A03D-0CAC-4828-A807-34A693F73859}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt.csproj", "{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-FC0A-4C1D-92DE-38D0662C257D}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
.gitattributes = .gitattributes .gitattributes = .gitattributes
.gitignore = .gitignore .gitignore = .gitignore
.tgitconfig = .tgitconfig .tgitconfig = .tgitconfig
build.cake = build.cake add-meta-files-to-sln.csx = add-meta-files-to-sln.csx
code.cleanup.full.ps1 = code.cleanup.full.ps1 code-cleanup-on-save.csx = code-cleanup-on-save.csx
code.quality.props = code.quality.props code-format.cmd = code-format.cmd
Directory.Build.props = Directory.Build.props Directory.Build.props = Directory.Build.props
dot.clean.cmd = dot.clean.cmd dot.sln.DotSettings = dot.sln.DotSettings
dotnet-tools.json = dotnet-tools.json dotnet-tools.json = dotnet-tools.json
git.pr.ps1 = git.pr.ps1 git-clean.ps1 = git-clean.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 push2nuget.ps1 = push2nuget.ps1
NSExt.sln.DotSettings = NSExt.sln.DotSettings
nuget.config = nuget.config
packable.props = packable.props
README.md = README.md README.md = README.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}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt\NSExt.csproj", "{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -45,13 +33,9 @@ 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 {70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.Build.0 = Debug|Any CPU {70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.ActiveCfg = Release|Any CPU {70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.Build.0 = Release|Any CPU {70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Release|Any CPU.Build.0 = Release|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,106 +0,0 @@
<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:Boolean x:Key="/Default/CodeEditing/TypingAssist/SkipClosingBracesOnTabInStringLiterals/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignmentInConditionalExpression/@EntryIndexedValue">DO_NOT_SHOW</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_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/=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/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: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_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: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: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/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 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/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/=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/CSharpFileLayoutPatterns/Pattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"&gt;
&lt;TypePattern&gt;
&lt;Entry&gt;
&lt;Entry.SortBy&gt;
&lt;Kind&gt;
&lt;Kind.Order&gt;
&lt;DeclarationKind&gt;Constant&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Field&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Constructor&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Destructor&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Delegate&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Event&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Enum&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Interface&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Property&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Indexer&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Method&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Struct&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Record&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Class&lt;/DeclarationKind&gt;
&lt;/Kind.Order&gt;
&lt;/Kind&gt;
&lt;Access&gt;
&lt;Access.Order&gt;
&lt;AccessModifier&gt;Public&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;Internal&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;ProtectedInternal&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;Protected&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;PrivateProtected&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;Private&lt;/AccessModifier&gt;
&lt;/Access.Order&gt;
&lt;/Access&gt;
&lt;Static /&gt;
&lt;Readonly /&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;/TypePattern&gt;
&lt;/Patterns&gt;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Aigc/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Biji/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Childs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Depts/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=fenlei/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFF/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Furion/@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/=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/=Meituan/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=miaosha/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=nicktitle/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=qudao/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Responsing/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Smzdm/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tabao/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=tablename/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taobao/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taoke/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tese/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=timesort/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=weixin/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=XBOXONE/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=youhui/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=yugao/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYMMDD/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYMMDDHHMMSSFFFZZZZ/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=zhiyou/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=zhuanlan/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>

View File

@ -1,65 +1 @@
# ns-ext # ns-ext
[](README.zh-CN.md) | **En**
The **ns-ext** is a .NET extension function library, containing the following types of extension modules:
| Features | File name |
|------------------------------------------|------------------------------------|
| Byte type extension | ByteExtensions.cs |
| Character Type Extensions | CharExtensions.cs |
| Date Type Extensions | DateTimeExtensions.cs |
| Database command type extension | DbCommandExtensions.cs |
| Decimal Number Type extension | DecimalExtensions.cs |
| Enumable type extension | EnumerableExtensions.cs |
| Enumeration type extension | EnumExtensions.cs |
| General type extension | GenericExtensions.cs |
| Integer type extension | IntExtensions.cs |
| Json Serialization option type extension | JsonSerializerOptionsExtensions.cs |
| Log type extension | LoggerExtensions.cs |
| Long integer extension | LongExtensions.cs |
| Object type extension | ObjectExtensions.cs |
| Stream type extension | StreamExtensions.cs |
| String type extension | StringExtensions.cs |
| Prototype type extension | TypeExtensions.cs |
| Resource locator type extension | UriExtensions.cs |
## Quick start
### Install
```shell
dotnet add package NSExt --prerelease
```
### Example
```c#
using NSExt.Extensions;
internal static class Program
{
private class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void Main(string[] args)
{
var person =
"""
{
"Name": "Jason",
"Age": "30"
}
""".Object<Person>();
Console.WriteLine(person.Json());
}
}
```
### Output
```json
{"name":"Jason","age":30}
```

View File

@ -1,65 +0,0 @@
# ns-ext
[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 |
## 快速开始
### 安装
```shell
dotnet add package NSExt --prerelease
```
### 示例
```c#
using NSExt.Extensions;
internal static class Program
{
private class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void Main(string[] args)
{
var person =
"""
{
"Name": "Jason",
"Age": "30"
}
""".Object<Person>();
Console.WriteLine(person.Json());
}
}
```
### 输出
```json
{"name":"Jason","age":30}
```

14
add-meta-files-to-sln.csx Normal file
View File

@ -0,0 +1,14 @@
using System.Text.RegularExpressions;
var slnFile = Directory.GetFiles(@".", "*.sln").First();
var content = File.ReadAllText(slnFile);
content = Regex.Replace(content,@"ProjectSection\(SolutionItems\) = preProject(?:.|\n)*?EndProjectSection",
$"""
ProjectSection(SolutionItems) = preProject
{string.Join('\n',
Directory.GetFiles(@".", "*").Where(x => !x.EndsWith(".sln"))
.Select(x=>$"\t\t{Path.GetFileName(x)} = {Path.GetFileName(x)}"))}
{'\t'}EndProjectSection
""");
Console.WriteLine(content);
File.WriteAllText(slnFile, content);

View File

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

16
code-cleanup-on-save.csx Normal file
View File

@ -0,0 +1,16 @@
var path = Directory.GetFiles(@".idea", "workspace.xml", SearchOption.AllDirectories).First();
const string findStr = """
&quot;keyToString&quot;: {
""";
const string replaceStr = """
&quot;keyToString&quot;: {
&quot;rider.code.cleanup.on.save&quot;: &quot;true&quot;,
""";
var content = File.ReadAllText(path);
if(content.Contains("rider.code.cleanup.on.save")){
Console.WriteLine("alreay added");
return;
}
content = content.Replace(findStr, replaceStr);
Console.WriteLine(content);
File.WriteAllText(path, content);

3
code-format.cmd Normal file
View File

@ -0,0 +1,3 @@
dot rbom -w
dot trim -w
dot tolf -w

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

50
dot.sln.DotSettings Normal file
View File

@ -0,0 +1,50 @@
<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/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;TypePattern&gt;
&lt;Entry&gt;
&lt;Entry.SortBy&gt;
&lt;Kind&gt;
&lt;Kind.Order&gt;
&lt;DeclarationKind&gt;Interface&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Class&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Record&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Enum&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Struct&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Delegate&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Event&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Constant&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Field&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Property&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Constructor&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Destructor&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Indexer&lt;/DeclarationKind&gt;
&lt;DeclarationKind&gt;Method&lt;/DeclarationKind&gt;
&lt;/Kind.Order&gt;
&lt;/Kind&gt;
&lt;Access&gt;
&lt;Access.Order&gt;
&lt;AccessModifier&gt;Private&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;PrivateProtected&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;Protected&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;ProtectedInternal&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;Internal&lt;/AccessModifier&gt;
&lt;AccessModifier&gt;Public&lt;/AccessModifier&gt;
&lt;/Access.Order&gt;
&lt;/Access&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;/TypePattern&gt;
&lt;/Patterns&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/=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:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">False</s:Boolean>
<s:String
x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">HINT</s:String>
</wpf:ResourceDictionary>

View File

@ -2,23 +2,6 @@
"version": 1, "version": 1,
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"cake.tool": {
"version": "3.1.0",
"commands": [
"dotnet-cake"
]
},
"dotnet-script": {
"version": "1.4.0",
"commands": [
"dotnet-script"
]
},
"jetbrains.resharper.globaltools": {
"version": "2023.2.0",
"commands": [
"jb"
]
}
} }
} }

1
git-clean.ps1 Normal file
View File

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

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": "7.0.100",
"rollForward": "latestMajor", "allowPrerelease": true,
"allowPrerelease": true "rollForward": "major"
}, },
"tools": { "tools": {
"dotnet": "7.0.0" "dotnet": "7.0.100"
} }
} }

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,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.cdn.azure.cn" value="https://nuget.cdn.azure.cn/v3/index.json" />
</packageSources>
</configuration>

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>

25
push2nuget.ps1 Normal file
View File

@ -0,0 +1,25 @@
Param(
# Nuget APIKey
[string] $apikey
)
if ($apikey -eq $null -or $apikey -eq "")
{
Write-Error "require apiKey";
return;
}
rm -r ./build/nupkgs
dotnet build -c Release
$files = Get-ChildItem -Path ./build/nupkgs/ -Filter *.nupkg
foreach($file in $files)
{
dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
nuget add $file.fullName -source d:\nuget-pkg
}
$files = Get-ChildItem -Path ./build/nupkgs/ -Filter *.snupkg
foreach($file in $files)
{
dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
nuget add $file.fullName -source d:\nuget-pkg
}

View File

@ -1,24 +1,22 @@
namespace NSExt.Extensions; namespace NSExt.Extensions;
/// <summary>
/// ByteExtensions
/// </summary>
public static class ByteExtensions public static class ByteExtensions
{ {
/// <summary> /// <summary>
/// base64编码 /// base64编码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待编码的字节数组</param>
/// <returns>编码后的base64字符串</returns> /// <returns>编码后的base64字符串</returns>
public static string Base64(this byte[] me) public static string Base64(this byte[] me)
{ {
return Convert.ToBase64String(me); return Convert.ToBase64String(me);
} }
/// <summary> /// <summary>
/// 将字节数组解码成字符串 /// 将字节数组解码成字符串
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字节数组</param>
/// <param name="e">字符串使用的编码方式</param> /// <param name="e">字符串使用的编码方式</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me, Encoding e) public static string HexDe(this byte[] me, Encoding e)
@ -26,10 +24,11 @@ public static class ByteExtensions
return e.GetString(me); return e.GetString(me);
} }
/// <summary> /// <summary>
/// 将字节数组解码成字符串 /// 将字节数组解码成字符串
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字节数组</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me) public static string HexDe(this byte[] me)
{ {
@ -39,23 +38,15 @@ public static class ByteExtensions
/// <summary> /// <summary>
/// 将字节数组转换成16进制字符串 /// 将字节数组转换成16进制字符串
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me"></param>
/// <param name="upperCase">是否大写</param> /// <param name="upperCase">是否大写</param>
/// <param name="splitShar">字节间分隔符</param> /// <param name="splitShar">字节间分隔符</param>
/// <param name="splitInterval">分隔符跳跃字节数</param> /// <returns></returns>
public static string Str(this IEnumerable<byte> me, bool upperCase = true, string splitShar = "" public static string String(this byte[] me, bool upperCase = true, string splitShar = null)
, int splitInterval = 1)
{ {
var sb = new StringBuilder(); var ret = BitConverter.ToString(me);
var i = 0; if (!upperCase) ret = ret.ToLower();
foreach (var c in me.Select(x => x.ToString(upperCase ? "X2" : "x2", CultureInfo.InvariantCulture))) { if (splitShar != "-") ret = ret.Replace("-", splitShar ?? string.Empty);
if (i++ % splitInterval == 0) { return ret;
_ = sb.Append(splitShar);
}
_ = sb.Append(c);
}
return sb.ToString();
} }
} }

View File

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

View File

@ -0,0 +1,89 @@
// ReSharper disable UnusedMember.Global
namespace NSExt.Extensions;
public static class DateTimeExtensions
{
/// <summary>
/// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串如2秒以前3天以前
/// </summary>
/// <param name="me">时间对象</param>
/// <returns>字符串</returns>
public static string TimeAgo(this DateTime me)
{
var ts = DateTime.Now - me;
if (ts.Days > 0) return ts.Days + "天前";
if (ts.Hours > 0) return ts.Hours + "小时前";
if (ts.Minutes > 0) return ts.Minutes + "分钟前";
return ts.Seconds + "秒前";
}
/// <summary>
/// 指定时间的世界协调时的unix时间戳形式
/// </summary>
/// <param name="me">指定时间</param>
/// <returns>unix时间戳</returns>
public static long TimeUnixUtc(this DateTime me)
{
return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
/// <summary>
/// 指定时间的世界协调时的unix时间戳形式毫秒
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static long TimeUnixUtcMs(this DateTime me)
{
return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000;
}
// ReSharper disable once InconsistentNaming
public static string yyyy_MM(this DateTime me)
{
return me.ToString("yyyy-MM");
}
// ReSharper disable once InconsistentNaming
public static string yyyy_MM_dd(this DateTime me)
{
return me.ToString("yyyy-MM-dd");
}
// ReSharper disable once InconsistentNaming
public static string yyyy_MM_dd_HH_mm(this DateTime me)
{
return me.ToString("yyyy-MM-dd HH:mm");
}
// ReSharper disable once InconsistentNaming
public static string yyyy_MM_dd_HH_mm_ss(this DateTime me)
{
return me.ToString("yyyy-MM-dd HH:mm:ss");
}
// ReSharper disable once InconsistentNaming
public static string yyyy_MM_dd_HH_mm_ss_fff(this DateTime me)
{
return me.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
// ReSharper disable once InconsistentNaming
public static string yyyyMM(this DateTime me)
{
return me.ToString("yyyyMM");
}
// ReSharper disable once InconsistentNaming
public static string yyyyMMdd(this DateTime me)
{
return me.ToString("yyyyMMdd");
}
}

View File

@ -0,0 +1,29 @@
namespace NSExt.Extensions;
public static class DbCommandExtensions
{
/// <summary>
/// 格式化参数拼接成完整的SQL语句
/// </summary>
/// <returns></returns>
public static string ParameterFormat(this DbCommand me)
{
//var aa = pars.ToDictionary(it => it.ParameterName, it => it.Value);
var sql = me.CommandText;
//应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10
for (var i = me.Parameters.Count - 1; i >= 0; i--)
sql = me.Parameters[i].DbType switch {
DbType.String or DbType.DateTime or DbType.Date or DbType.Time or DbType.DateTime2
or DbType.DateTimeOffset or DbType.Guid or DbType.VarNumeric or DbType.AnsiStringFixedLength
or DbType.AnsiString
or DbType.StringFixedLength =>
sql.Replace(me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'")
, DbType.Boolean => sql.Replace(me.Parameters[i].ParameterName
, Convert.ToBoolean(me.Parameters[i].Value) ? "1" : "0")
, _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString())
};
return sql;
}
}

View File

@ -0,0 +1,16 @@
namespace NSExt.Extensions;
public static class DecimalExtensions
{
/// <summary>
/// 四舍五入后的近似值
/// </summary>
/// <param name="me">数字</param>
/// <param name="place">小数点位数</param>
/// <returns>处理后的值</returns>
public static decimal Round(this decimal me, int place)
{
var dec = Math.Round(me, place);
return dec;
}
}

View File

@ -0,0 +1,17 @@
namespace NSExt.Extensions;
public static class EnumExtensions
{
/// <summary>
/// 获取枚举的description属性
/// </summary>
/// <param name="e">枚举对象</param>
/// <returns>description属性</returns>
public static string Desc(this Enum e)
{
var t = e.GetType();
var fi = t.GetField(Enum.GetName(t, e)!);
var attrs = (DescriptionAttribute[])fi!.GetCustomAttributes(typeof(DescriptionAttribute), false);
return (attrs.Length != 0 ? attrs[0].Description : Enum.GetName(t, e)) ?? "";
}
}

View File

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

View File

@ -1,15 +1,12 @@
namespace NSExt.Extensions; namespace NSExt.Extensions;
/// <summary>
/// GenericExtensions
/// </summary>
public static class GenericExtensions public static class GenericExtensions
{ {
/// <summary> /// <summary>
/// 从指定的对象拷贝属性 /// 从指定的对象拷贝属性
/// </summary> /// </summary>
/// <typeparam name="T">对象类型</typeparam> /// <typeparam name="T">对象类型</typeparam>
/// <param name="me">me</param> /// <param name="me">拷贝目标</param>
/// <param name="copyObj">拷贝来源</param> /// <param name="copyObj">拷贝来源</param>
/// <param name="propNameList">需要处理的属性名</param> /// <param name="propNameList">需要处理的属性名</param>
/// <param name="isIncludeOrExclude">True包含false排除</param> /// <param name="isIncludeOrExclude">True包含false排除</param>
@ -17,24 +14,27 @@ public static class GenericExtensions
, bool isIncludeOrExclude = false) , bool isIncludeOrExclude = false)
{ {
foreach (var p in me.GetType().GetProperties()) { foreach (var p in me.GetType().GetProperties()) {
if (!p.CanWrite) { if (!p.CanWrite) continue;
continue; bool isSet;
if (isIncludeOrExclude)
isSet = propNameList?.Contains(p.Name) ?? false;
else
isSet = !propNameList?.Contains(p.Name) ?? true;
if (isSet) p.SetValue(me, copyObj.GetType().GetProperty(p.Name)?.GetValue(copyObj, null), null);
}
} }
var isSet = isIncludeOrExclude
? propNameList?.Contains(p.Name) ?? false
: !propNameList?.Contains(p.Name) ?? true;
if (isSet) {
p.SetValue(me, copyObj.GetType().GetProperty(p.Name)?.GetValue(copyObj, null), null);
}
}
}
/// <summary> /// <summary>
/// 判断是否与某对象相等 /// 判断是否与某对象相等
/// </summary> /// </summary>
public static T Is<T>(this T me, T compare, T ret) /// <typeparam name="T"></typeparam>
where T : struct /// <param name="me"></param>
/// <param name="compare"></param>
/// <param name="ret"></param>
/// <returns></returns>
public static T Is<T>(this T me, T compare, T ret) where T : struct
{ {
return me.Equals(compare) ? ret : me; return me.Equals(compare) ? ret : me;
} }

View File

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

View File

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

View File

@ -0,0 +1,49 @@
// ReSharper disable TemplateIsNotCompileTimeConstantProblem
namespace NSExt.Extensions;
public static class LoggerExtensions
{
private static string CallerInfoMessage(object message, string callerName, string callerFilePath
, int callerLineNumber)
{
return
$"{message} <s:{Environment.CurrentManagedThreadId}#{callerName}@{Path.GetFileName(callerFilePath)}:{callerLineNumber}>";
}
public static void Debug(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
me.LogDebug(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
}
public static void Error(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
me.LogError(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
}
public static void Fatal(this ILogger me, object message, Exception ex = null
, [CallerMemberName] string callerName = null, [CallerFilePath] string callerFilePath = null
, [CallerLineNumber] int callerLineNumber = 0)
{
if (ex is null)
me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
else
me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber), ex);
}
public static void Info(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
me.LogInformation(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
}
public static void Warn(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
me.LogWarning(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
}
}

View File

@ -0,0 +1,27 @@
namespace NSExt.Extensions;
public static class LongExtensions
{
/// <summary>
/// 判断枚举是否包含某个位
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="me"></param>
/// <param name="flag"></param>
/// <returns></returns>
public static bool HasFlag<T>(this long me, T flag) where T : Enum
{
var val = (long)(object)flag;
return (me & val) == val;
}
/// <summary>
/// 1970毫秒数转换成日期对象
/// </summary>
/// <param name="msFrom1970"></param>
/// <returns></returns>
public static DateTime Time(this long msFrom1970)
{
return new DateTime(1970, 1, 1).AddMilliseconds(msFrom1970).ToLocalTime();
}
}

View File

@ -0,0 +1,18 @@
using System.Text.Json;
namespace NSExt.Extensions;
public static class ObjectExtensions
{
/// <summary>
/// 将一个对象序列化成json文本
/// </summary>
/// <param name="me">指定对象</param>
/// <param name="format">是否格式化</param>
/// <returns>json文本</returns>
public static string Json(this object me, bool format = false)
{
return JsonSerializer.Serialize(
me, new JsonSerializerOptions { WriteIndented = format, PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
}

View File

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

View File

@ -1,25 +1,41 @@
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
#pragma warning disable CA1720
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
using NSExt.Constant;
namespace NSExt.Extensions; namespace NSExt.Extensions;
/// <summary>
/// StringExtensions
/// </summary>
#pragma warning disable CodeLinesAnalyzer
public static class StringExtensions public static class StringExtensions
{ {
private static readonly JsonSerializerOptions _defaultJsonSerializerOptions
= default(JsonSerializerOptions).NewJsonSerializerOptions();
/// <summary>
/// MD5 hmac编码
/// </summary>
/// <param name="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)
{
using var md5Hmac = new HMACMD5(e.GetBytes(key));
return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
/// <summary> /// <summary>
/// aes加密 /// aes加密
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">要加密的串</param>
/// <param name="key">密钥</param> /// <param name="key">密钥</param>
public static string Aes(this string me, string key) /// <param name="cipherMode">指定要用于加密的块密码模式。</param>
/// <param name="paddingMode">指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型。</param>
/// <returns></returns>
public static string Aes(this string me, string key, CipherMode cipherMode = CipherMode.ECB
, PaddingMode paddingMode = PaddingMode.PKCS7)
{ {
using var aes = System.Security.Cryptography.Aes.Create(); using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7; aes.Padding = PaddingMode.PKCS7;
@ -31,12 +47,17 @@ public static class StringExtensions
return decrypted.Base64(); return decrypted.Base64();
} }
/// <summary> /// <summary>
/// aes解密 /// aes解密
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">要加密的串</param>
/// <param name="key">密钥</param> /// <param name="key">密钥</param>
public static string AesDe(this string me, string key) /// <param name="cipherMode">指定要用于加密的块密码模式。</param>
/// <param name="paddingMode">指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型。</param>
/// <returns></returns>
public static string AesDe(this string me, string key, CipherMode cipherMode = CipherMode.ECB
, PaddingMode paddingMode = PaddingMode.PKCS7)
{ {
using var aes = System.Security.Cryptography.Aes.Create(); using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7; aes.Padding = PaddingMode.PKCS7;
@ -51,7 +72,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// base64编码 /// base64编码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待base64编码的字符串</param>
/// <param name="e">字符串的编码方式</param> /// <param name="e">字符串的编码方式</param>
/// <returns>编码后的base64字符串</returns> /// <returns>编码后的base64字符串</returns>
public static string Base64(this string me, Encoding e) public static string Base64(this string me, Encoding e)
@ -62,7 +83,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// base64解码 /// base64解码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待解码的字符串</param>
/// <returns>解码后的原始字节数组</returns> /// <returns>解码后的原始字节数组</returns>
public static byte[] Base64De(this string me) public static byte[] Base64De(this string me)
{ {
@ -72,17 +93,18 @@ public static class StringExtensions
/// <summary> /// <summary>
/// base64解码 /// base64解码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待解码的字符串</param>
/// <param name="e">字符串的编码方式</param> /// <param name="e">字符串的编码方式</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string Base64De(this string me, Encoding e) public static string Base64De(this string me, Encoding e)
{ {
return e.GetString(me.Base64De()); return e.GetString(Base64De(me));
} }
/// <summary> /// <summary>
/// 将易于web传输的base64web字符串转换为原生base64 /// 将易于web传输的base64web字符串转换为原生base64
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns>原生base64</returns> /// <returns>原生base64</returns>
public static string Base64Sys(this string me) public static string Base64Sys(this string me)
{ {
@ -92,6 +114,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将原生base64字符串转换成易于web传输的字符串 /// 将原生base64字符串转换成易于web传输的字符串
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns>易于web传输的字符串</returns> /// <returns>易于web传输的字符串</returns>
public static string Base64Web(this string me) public static string Base64Web(this string me)
{ {
@ -101,7 +124,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待转换字符串</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
public static DateTime DateTime(this string me) public static DateTime DateTime(this string me)
{ {
@ -111,7 +134,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待转换字符串</param>
/// <param name="format">日期格式</param> /// <param name="format">日期格式</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExact(this string me, string format) public static DateTime DateTimeExact(this string me, string format)
@ -122,7 +145,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待转换字符串</param>
/// <param name="format">日期格式</param> /// <param name="format">日期格式</param>
/// <param name="def">转换失败时返回的日期对象</param> /// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
@ -133,31 +156,33 @@ public static class StringExtensions
: ret; : ret;
} }
/// <summary> /// <summary>
/// 将字符串转换成日期对象 /// 将字符串转换成日期对象
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">待转换字符串</param>
/// <param name="def">转换失败时返回的日期对象</param> /// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns> /// <returns>转换后的日期对象</returns>
public static DateTime DateTimeTry(this string me, DateTime def) public static DateTime DateTimeTry(this string me, DateTime def)
{ {
return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, out var ret) ? def : ret; return !System.DateTime.TryParse(me, out var ret) ? def : ret;
} }
/// <summary> /// <summary>
/// string to decimal /// string to decimal
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">string</param>
/// <returns>decimal</returns> /// <returns>decimal</returns>
public static decimal Dec(this string me) public static decimal Dec(this string me)
{ {
return decimal.Parse(me, CultureInfo.CurrentCulture); return decimal.Parse(me, CultureInfo.CurrentCulture);
} }
/// <summary> /// <summary>
/// 尝试将字符串转为decimal /// 尝试将字符串转为decimal
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="def">转换失败后返回的默认值</param> /// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的decimal</returns> /// <returns>转换后的decimal</returns>
public static decimal DecTry(this string me, decimal def) public static decimal DecTry(this string me, decimal def)
@ -165,10 +190,11 @@ public static class StringExtensions
return !decimal.TryParse(me, out var ret) ? def : ret; return !decimal.TryParse(me, out var ret) ? def : ret;
} }
/// <summary> /// <summary>
/// string to double /// string to double
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">string</param>
/// <returns>Int32</returns> /// <returns>Int32</returns>
public static double Double(this string me) public static double Double(this string me)
{ {
@ -178,17 +204,23 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成枚举对象 /// 将字符串转换成枚举对象
/// </summary> /// </summary>
public static T Enum<T>(this string name) /// <typeparam name="T"></typeparam>
where T : Enum /// <param name="name"></param>
/// <returns></returns>
public static T Enum<T>(this string name) where T : Enum
{ {
return (T)System.Enum.Parse(typeof(T), name, true); return (T)System.Enum.Parse(typeof(T), name, true);
} }
/// <summary> /// <summary>
/// 将字符串转换成枚举对象 /// 将字符串转换成枚举对象
/// </summary> /// </summary>
public static T EnumTry<T>(this string name, T def) /// <typeparam name="T"></typeparam>
where T : Enum /// <param name="name"></param>
/// <param name="def"></param>
/// <returns></returns>
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; return !System.Enum.TryParse(typeof(T), name, out var ret) ? def : (T)ret;
} }
@ -196,17 +228,19 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to float /// string to float
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">string</param>
/// <returns>Int32</returns> /// <returns>Int32</returns>
public static float Float(this string me) public static float Float(this string me)
{ {
return float.Parse(me, CultureInfo.CurrentCulture); return float.Parse(me, CultureInfo.CurrentCulture);
} }
/// <summary> /// <summary>
/// 将字符串转为guid /// 将字符串转为guid
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <returns></returns>
public static Guid Guid(this string me) public static Guid Guid(this string me)
{ {
return System.Guid.Parse(me); return System.Guid.Parse(me);
@ -215,17 +249,19 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成guid /// 将字符串转换成guid
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="def">转换失败的返回值</param> /// <param name="def">转换失败的返回值</param>
/// <returns></returns>
public static Guid Guid(this string me, Guid def) public static Guid Guid(this string me, Guid def)
{ {
return System.Guid.TryParse(me, out var ret) ? ret : def; return System.Guid.TryParse(me, out var ret) ? ret : def;
} }
/// <summary> /// <summary>
/// 将字符串转换成字节数组形式 /// 将字符串转换成字节数组形式
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>字节数组</returns> /// <returns>字节数组</returns>
public static byte[] Hex(this string me, Encoding e) public static byte[] Hex(this string me, Encoding e)
@ -236,25 +272,24 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 将字符串转换成字节数组形式 /// 将字符串转换成字节数组形式
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <returns>字节数组</returns> /// <returns>字节数组</returns>
public static byte[] Hex(this string me) public static byte[] Hex(this string me)
{ {
return me.Hex(Encoding.UTF8); return me.Hex(Encoding.UTF8);
} }
/// <summary> /// <summary>
/// 对一个字符串进行sha1 hash运算 /// 对一个字符串进行sha1 hash运算
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">对一个字符串进行sha1 hash运算</param>
/// <param name="secret">密钥</param> /// <param name="secret">密钥</param>
/// <param name="e">使用的编码</param> /// <param name="e">使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns> /// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string HmacSha1(this string me, string secret, Encoding e) public static string HmacSha1(this string me, string secret, Encoding e)
{ {
#pragma warning disable CA5350
using var hmacSha1 = new HMACSHA1(e.GetBytes(secret)); using var hmacSha1 = new HMACSHA1(e.GetBytes(secret));
#pragma warning restore CA5350
return BitConverter.ToString(hmacSha1.ComputeHash(e.GetBytes(me))) return BitConverter.ToString(hmacSha1.ComputeHash(e.GetBytes(me)))
.Replace("-", string.Empty) .Replace("-", string.Empty)
@ -264,6 +299,8 @@ public static class StringExtensions
/// <summary> /// <summary>
/// html编码 /// html编码
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string Html(this string me) public static string Html(this string me)
{ {
return HttpUtility.HtmlEncode(me); return HttpUtility.HtmlEncode(me);
@ -272,7 +309,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 解码html编码 /// 解码html编码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">html编码后的字符串</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string HtmlDe(this string me) public static string HtmlDe(this string me)
{ {
@ -282,7 +319,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// string to Int32 /// string to Int32
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">string</param>
/// <returns>Int32</returns> /// <returns>Int32</returns>
public static int Int32(this string me) public static int Int32(this string me)
{ {
@ -292,7 +329,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 尝试将字符串转为int32 /// 尝试将字符串转为int32
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="def">转换失败后返回的默认值</param> /// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int32</returns> /// <returns>转换后的int32</returns>
public static int Int32Try(this string me, int def) public static int Int32Try(this string me, int def)
@ -300,10 +337,11 @@ public static class StringExtensions
return !int.TryParse(me, out var ret) ? def : ret; return !int.TryParse(me, out var ret) ? def : ret;
} }
/// <summary> /// <summary>
/// string to Int64 /// string to Int64
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">string</param>
/// <returns>Int64</returns> /// <returns>Int64</returns>
public static long Int64(this string me) public static long Int64(this string me)
{ {
@ -313,7 +351,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 尝试将字符串转为int64 /// 尝试将字符串转为int64
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="def">转换失败后返回的默认值</param> /// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int64</returns> /// <returns>转换后的int64</returns>
public static long Int64Try(this string me, long def) public static long Int64Try(this string me, long def)
@ -324,66 +362,66 @@ public static class StringExtensions
/// <summary> /// <summary>
/// ipv4格式转int32格式 /// ipv4格式转int32格式
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static int IpV4ToInt32(this string me) public static int IpV4ToInt32(this string me)
{ {
return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0); return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0);
} }
/// <summary> /// <summary>
/// 是否base64字符串 /// 是否base64字符串
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <returns></returns>
public static bool IsBase64String(this string me) public static bool IsBase64String(this string me)
{ {
// 一个合法的Base64有着以下特征 // 一个合法的Base64有着以下特征
// 字符串的长度为4的整数倍。 // 字符串的长度为4的整数倍。
// 字符串的符号取值只能在A -Z, a -z, 0 -9, +, /, =共计65个字符中且 = 如果出现就必须在结尾出现。 // 字符串的符号取值只能在A -Z, a -z, 0 -9, +, /, =共计65个字符中且 = 如果出现就必须在结尾出现。
if (!me.All(x => x.IsBase64Character())) { if (!me.All(x => x.IsBase64Character())) return false;
return false; if (me.Length % 4 != 0) return false;
}
if (me.Length % 4 != 0) {
return false;
}
var firstEqualSignPos = me.IndexOf('='); var firstEqualSignPos = me.IndexOf('=');
if (firstEqualSignPos < 0) { if (firstEqualSignPos < 0) return true;
return true;
}
var lastEqualSignPos = me.LastIndexOf('='); var lastEqualSignPos = me.LastIndexOf('=');
return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '='); return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '=');
} }
/// <summary> /// <summary>
/// 中文姓名打马赛克 /// 中文姓名打马赛克
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string MaskChineseName(this string me) public static string MaskChineseName(this string me)
{ {
return me.Length == 2 ? "*" + me[1..] : me[..1] + "*" + me[^1..]; if (me.Length == 2) return "*" + me[1..];
return me[..1] + "*" + me[^1..];
} }
/// <summary> /// <summary>
/// 对一个手机号进行掩码处理 /// 对一个手机号进行掩码处理
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">手机号</param>
/// <returns>掩码后的手机号</returns> /// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me) public static string MaskMobile(this string me)
{ {
return Regexes.RegexMobile.Replace(me, "$1****$2"); return new Regex(@"^(\d{3})\d{4}(\d{4})$").Replace(me, "$1****$2");
} }
/// <summary> /// <summary>
/// 对一个字符串进行md5hash运算 /// 对一个字符串进行md5hash运算
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns> /// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Md5(this string me, Encoding e) public static string Md5(this string me, Encoding e)
{ {
#pragma warning disable CA5351 using var md5 = MD5.Create();
return BitConverter.ToString(MD5.HashData(e.GetBytes(me))) return BitConverter.ToString(md5.ComputeHash(e.GetBytes(me)))
#pragma warning restore CA5351
.Replace("-", string.Empty) .Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture); .ToLower(CultureInfo.CurrentCulture);
} }
@ -391,7 +429,7 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身 /// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">指定字符串</param>
/// <param name="defVal">指定的默认值</param> /// <param name="defVal">指定的默认值</param>
/// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns> /// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns>
public static string NullOrEmpty(this string me, string defVal) public static string NullOrEmpty(this string me, string defVal)
@ -399,9 +437,12 @@ public static class StringExtensions
return me.AsEnumerable().NullOrEmpty() ? defVal : me; return me.AsEnumerable().NullOrEmpty() ? defVal : me;
} }
/// <summary> /// <summary>
/// null或空白字符 /// null或空白字符
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static bool NullOrWhiteSpace(this string me) public static bool NullOrWhiteSpace(this string me)
{ {
return string.IsNullOrWhiteSpace(me); return string.IsNullOrWhiteSpace(me);
@ -410,30 +451,32 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 反序列化一个文件获得指定类型的数据对象 /// 反序列化一个文件获得指定类型的数据对象
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">等待反序列化的json文本</param>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns> /// <returns>反序列化后生成的对象</returns>
public static T Object<T>(this string me, JsonSerializerOptions options = null) public static T Object<T>(this string me, JsonSerializerOptions options = null)
{ {
return JsonSerializer.Deserialize<T>(me, options); return JsonSerializer.Deserialize<T>(me, options ?? _defaultJsonSerializerOptions);
} }
/// <summary> /// <summary>
/// 反序列化一个文件获得指定类型的数据对象 /// 反序列化一个文件获得指定类型的数据对象
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">等待反序列化的json文本</param>
/// <param name="type">实际类型</param> /// <param name="type">实际类型</param>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns> /// <returns>反序列化后生成的对象</returns>
public static object Object(this string me, Type type, JsonSerializerOptions options = null) public static object Object(this string me, Type type, JsonSerializerOptions options = null)
{ {
return JsonSerializer.Deserialize(me, type, options); return JsonSerializer.Deserialize(me, type, options ?? _defaultJsonSerializerOptions);
} }
/// <summary> /// <summary>
/// 生成密码 /// 生成密码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">密码原文</param>
/// <returns>密文</returns> /// <returns>密文</returns>
public static string Pwd(this string me) public static string Pwd(this string me)
{ {
@ -443,118 +486,90 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 移除字符串中的html标签 /// 移除字符串中的html标签
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <returns>处理之后的字符串</returns> /// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me) public static string RemoveHtmlTag(this string me)
{ {
return Regexes.RegexHtmlTag.Replace(me, string.Empty); return new Regex(@"<[^>]*>").Replace(me, "");
} }
/// <summary> /// <summary>
/// 删除换行符 /// 删除换行符
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string RemoveWrapped(this string me) public static string RemoveWrapped(this string me)
{ {
return me.Replace("\r", string.Empty).Replace("\n", string.Empty); return me.Replace("\r", "").Replace("\n", "");
} }
/// <summary> /// <summary>
/// 对一个字符串进行sha1 hash运算 /// 对一个字符串进行sha1 hash运算
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <param name="e">字符串使用的编码</param> /// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns> /// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Sha1(this string me, Encoding e) public static string Sha1(this string me, Encoding e)
{ {
#pragma warning disable CA5350 using var sha1 = SHA1.Create();
return BitConverter.ToString(SHA1.HashData(e.GetBytes(me))) return BitConverter.ToString(sha1.ComputeHash(e.GetBytes(me)))
#pragma warning restore CA5350
.Replace("-", string.Empty) .Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture); .ToLower(CultureInfo.CurrentCulture);
} }
/// <summary> /// <summary>
/// 蛇形命名 /// 蛇形命名
/// </summary> /// </summary>
public static string SnakeCase(this string me) /// <param name="me"></param>
/// <returns></returns>
public static string Snakecase(this string me)
{ {
return Regexes.RegexUpLetter.Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-'); return Regex.Replace(me, "([A-Z])", "-$1").ToLower().TrimStart('-');
} }
/// <summary> /// <summary>
/// 截取指定长度的字符串代替substring /// 截取指定长度的字符串代替substring
/// </summary> /// </summary>
/// <param name="me"></param>
/// <param name="startIndex"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string Sub(this string me, int startIndex, int length) public static string Sub(this string me, int startIndex, int length)
{ {
if (startIndex + length > me.Length) { if (startIndex + length > me.Length) length = me.Length - startIndex;
length = me.Length - startIndex;
}
return me.Substring(startIndex, length); return me.Substring(startIndex, length);
} }
/// <summary> /// <summary>
/// 纯文本字符串转html /// 纯文本字符串转html
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string Text2Html(this string me) public static string Text2Html(this string me)
{ {
return $"<pre>{me}</pre>"; return $"<pre>{me}</pre>";
} }
/// <summary>
/// 首字母小写
/// </summary>
public static string ToLowerCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me)
? me
: string.Concat( //
me[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(), me.AsSpan(1));
}
/// <summary>
/// 首字母大写
/// </summary>
public static string ToUpperCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me) ? me : string.Concat(me[0].ToString().ToUpperInvariant(), me.AsSpan(1));
}
/// <summary> /// <summary>
/// 将连续多个空格替换成一个空格 /// 将连续多个空格替换成一个空格
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string TrimSpaces(this string me) public static string TrimSpaces(this string me)
{ {
var ret = me.Replace(" ", " "); var ret = me.Replace(" ", " ");
// ReSharper disable once TailRecursiveCall // ReSharper disable once TailRecursiveCall
return ret == me ? ret : ret.TrimSpaces(); return ret == me ? ret : TrimSpaces(ret);
} }
/// <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> /// <summary>
/// url编码 /// url编码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">字符串</param>
/// <returns>url编码后的字符串</returns> /// <returns>url编码后的字符串</returns>
public static string Url(this string me) public static string Url(this string me)
{ {
@ -564,28 +579,10 @@ public static class StringExtensions
/// <summary> /// <summary>
/// 解码url编码 /// 解码url编码
/// </summary> /// </summary>
/// <param name="me">me</param> /// <param name="me">url编码后的字符串</param>
/// <returns>解码后的原始字符串</returns> /// <returns>解码后的原始字符串</returns>
public static string UrlDe(this string me) public static string UrlDe(this string me)
{ {
return Uri.UnescapeDataString(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,13 +1,13 @@
namespace NSExt.Extensions; namespace NSExt.Extensions;
/// <summary>
/// TypeExtensions
/// </summary>
public static class TypeExtensions public static class TypeExtensions
{ {
/// <summary> /// <summary>
/// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。 /// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。
/// </summary> /// </summary>
/// <param name="me"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> GetCustomAttributesIncludingBaseInterfaces<T>(this Type me) public static IEnumerable<T> GetCustomAttributesIncludingBaseInterfaces<T>(this Type me)
{ {
var attributeType = typeof(T); var attributeType = typeof(T);

View File

@ -1,13 +1,12 @@
namespace NSExt.Extensions; namespace NSExt.Extensions;
/// <summary>
/// UriExtensions
/// </summary>
public static class UriExtensions public static class UriExtensions
{ {
/// <summary> /// <summary>
/// 移除url的Scheme /// 移除url的Scheme
/// </summary> /// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string RemoveScheme(this Uri me) public static string RemoveScheme(this Uri me)
{ {
return "//" + me.Authority + me.PathAndQuery; return "//" + me.Authority + me.PathAndQuery;

View File

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

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);
// }
}

16
src/NSExt.csproj Normal file
View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="MinVer" Version="4.3.0-beta.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -1,24 +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>
public LocalizationAttribute(Type resourceClass)
{
ResourceClass = resourceClass;
}
/// <summary>
/// Gets or sets 资源类型
/// </summary>
/// <value>
/// 资源类型
/// </value>
public Type ResourceClass { get; set; }
}

View File

@ -1,26 +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>
public ResourceDescriptionAttribute(string resourceName)
{
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,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,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,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../code.quality.props"/>
<Import Project="../../packable.props"/>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0-rc.1.23419.4"/>
</ItemGroup>
<ItemGroup>
<None Include="../../logo.png" Pack="true" PackagePath=""/>
</ItemGroup>
</Project>

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);