diff --git a/.editorconfig b/.editorconfig
index 8c3845c..2127d46 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,12 +1,28 @@
root = true
[*]
-indent_style = space
-indent_size = 4
-end_of_line = lf
charset = utf-8
+end_of_line = lf
+ij_xml_attribute_wrap = off
+ij_xml_text_wrap = off
+indent_size = 4
+indent_style = space
+insert_final_newline = false
trim_trailing_whitespace = true
+[*.cs]
+dotnet_analyzer_diagnostic.severity = warning
+dotnet_diagnostic.CA1707.severity = none
+dotnet_diagnostic.CA1720.severity = none
+dotnet_diagnostic.CA5350.severity = none
+dotnet_diagnostic.CA5351.severity = none
+dotnet_diagnostic.IDE0008.severity = none
+dotnet_diagnostic.IDE0017.severity = none
+dotnet_diagnostic.IDE0048.severity = none
+dotnet_diagnostic.IDE0055.severity = none
+dotnet_diagnostic.IDE0058.severity = none
+dotnet_diagnostic.IDE0160.severity = none
+
# ReSharper properties
resharper_align_linq_query = true
@@ -23,23 +39,27 @@ resharper_align_multline_type_parameter_constrains = true
resharper_align_multline_type_parameter_list = true
resharper_align_tuple_components = true
resharper_allow_comment_after_lbrace = true
+resharper_blank_lines_before_single_line_comment = 1
resharper_csharp_empty_block_style = together_same_line
resharper_csharp_outdent_commas = true
+resharper_csharp_place_type_constraints_on_same_line = false
resharper_csharp_stick_comment = false
resharper_csharp_wrap_before_comma = true
-resharper_indent_nested_foreach_stmt = true
resharper_indent_nested_for_stmt = true
+resharper_indent_nested_foreach_stmt = true
resharper_indent_nested_while_stmt = true
resharper_indent_preprocessor_if = usual_indent
resharper_indent_preprocessor_other = usual_indent
resharper_int_align = true
resharper_keep_existing_arrangement = false
resharper_place_linq_into_on_new_line = false
+resharper_place_simple_embedded_statement_on_same_line = false
resharper_place_simple_switch_expression_on_single_line = true
resharper_wrap_before_eq = true
resharper_wrap_chained_method_calls = chop_if_long
resharper_wrap_switch_expression = chop_if_long
+
# Microsoft .NET properties
csharp_indent_braces = false
csharp_new_line_before_open_brace = local_functions, methods, types
\ No newline at end of file
diff --git a/add-meta-files-to-sln.csx b/AddMetaFilesToSln.csx
similarity index 100%
rename from add-meta-files-to-sln.csx
rename to AddMetaFilesToSln.csx
diff --git a/code-cleanup-on-save.csx b/CodeCleanupOnSave.csx
similarity index 100%
rename from code-cleanup-on-save.csx
rename to CodeCleanupOnSave.csx
diff --git a/CodeQuality.props b/CodeQuality.props
new file mode 100644
index 0000000..df0775d
--- /dev/null
+++ b/CodeQuality.props
@@ -0,0 +1,17 @@
+
+
+ ../StyleCopAnalyzers.ruleset
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
index f6fcf75..11cee10 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,9 +1,11 @@
enable
- ../build/$(MSBuildProjectName)/bin
- ../build/$(MSBuildProjectName)/obj
- $(BaseIntermediateOutputPath)
+ ../dist
+ ../dist
+ $(BaseOutputPath)/$(MSBuildProjectName)/bin
+ $(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj
+ $(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj
nsnail
NSExt
© 2006-2022 nsnail
diff --git a/ImageOptimize.csx b/ImageOptimize.csx
new file mode 100644
index 0000000..8e6aca7
--- /dev/null
+++ b/ImageOptimize.csx
@@ -0,0 +1,45 @@
+/*
+ for %%i in (*.png) do pngquant %%i --force --output %%i --skip-if-larger
+ for %%i in (*.jpg) do jpegtran -copy none -optimize -perfect %%i %%i
+ *
+ */
+
+ var files = Directory.EnumerateFiles(".", "*.png"
+ , new EnumerationOptions {
+ RecurseSubdirectories = true
+ , AttributesToSkip = FileAttributes.ReparsePoint
+ , IgnoreInaccessible = true
+ })
+ .ToArray();
+
+
+ Parallel.ForEach(files, file => {
+ var startInfo = new ProcessStartInfo {
+ FileName = "pngquant"
+ , Arguments
+ = $"\"{file}\" --force --output \"{file}\" --skip-if-larger"
+ };
+ using var p = Process.Start(startInfo);
+ p.WaitForExit();
+ Console.WriteLine($"{file}: {p.ExitCode}");
+ });
+
+ files = new[] { "*.jpg", "*.jpeg" }
+ .SelectMany(x => Directory.EnumerateFiles(
+ ".", x
+ , new EnumerationOptions {
+ RecurseSubdirectories = true
+ , AttributesToSkip = FileAttributes.ReparsePoint
+ , IgnoreInaccessible = true
+ }))
+ .ToArray();
+
+ Parallel.ForEach(files, file => {
+ var startInfo = new ProcessStartInfo {
+ FileName = "jpegtran"
+ , Arguments = $"-copy none -optimize -perfect \"{file}\" \"{file}\""
+ };
+ using var p = Process.Start(startInfo);
+ p.WaitForExit();
+ Console.WriteLine($"{file}: {p.ExitCode}");
+ });
\ No newline at end of file
diff --git a/NSExt.sln b/NSExt.sln
index 4e16c72..d4e6c45 100644
--- a/NSExt.sln
+++ b/NSExt.sln
@@ -11,17 +11,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-F
.gitattributes = .gitattributes
.gitignore = .gitignore
.tgitconfig = .tgitconfig
- add-meta-files-to-sln.csx = add-meta-files-to-sln.csx
- code-cleanup-on-save.csx = code-cleanup-on-save.csx
+ AddMetaFilesToSln.csx = AddMetaFilesToSln.csx
+ build.cake = build.cake
code-format.cmd = code-format.cmd
+ CodeCleanupOnSave.csx = CodeCleanupOnSave.csx
+ CodeQuality.props = CodeQuality.props
Directory.Build.props = Directory.Build.props
dot.sln.DotSettings = dot.sln.DotSettings
dotnet-tools.json = dotnet-tools.json
- git-clean.ps1 = git-clean.ps1
+ git-clean.cmd = git-clean.cmd
global.json = global.json
+ ImageOptimize.csx = ImageOptimize.csx
LICENSE = LICENSE
push2nuget.ps1 = push2nuget.ps1
README.md = README.md
+ stylecop.json = stylecop.json
+ StyleCopAnalyzers.ruleset = StyleCopAnalyzers.ruleset
EndProjectSection
EndProject
Global
diff --git a/dot.sln.DotSettings b/NSExt.sln.DotSettings
similarity index 57%
rename from dot.sln.DotSettings
rename to NSExt.sln.DotSettings
index 205c3ab..24a4bdd 100644
--- a/dot.sln.DotSettings
+++ b/NSExt.sln.DotSettings
@@ -1,6 +1,22 @@
-
+
+ True
+ True
+ True
+ True
+ False
+ 1
+ 1
+ OFF
+ HINT
+ Required
+ Required
+ Required
+ Required
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+
<?xml version="1.0" encoding="utf-16"?>
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
<TypePattern>
@@ -8,43 +24,38 @@
<Entry.SortBy>
<Kind>
<Kind.Order>
- <DeclarationKind>Interface</DeclarationKind>
- <DeclarationKind>Class</DeclarationKind>
- <DeclarationKind>Record</DeclarationKind>
- <DeclarationKind>Enum</DeclarationKind>
- <DeclarationKind>Struct</DeclarationKind>
- <DeclarationKind>Delegate</DeclarationKind>
- <DeclarationKind>Event</DeclarationKind>
<DeclarationKind>Constant</DeclarationKind>
<DeclarationKind>Field</DeclarationKind>
- <DeclarationKind>Property</DeclarationKind>
<DeclarationKind>Constructor</DeclarationKind>
<DeclarationKind>Destructor</DeclarationKind>
+ <DeclarationKind>Delegate</DeclarationKind>
+ <DeclarationKind>Event</DeclarationKind>
+ <DeclarationKind>Enum</DeclarationKind>
+ <DeclarationKind>Interface</DeclarationKind>
+ <DeclarationKind>Property</DeclarationKind>
<DeclarationKind>Indexer</DeclarationKind>
<DeclarationKind>Method</DeclarationKind>
+ <DeclarationKind>Struct</DeclarationKind>
+ <DeclarationKind>Record</DeclarationKind>
+ <DeclarationKind>Class</DeclarationKind>
</Kind.Order>
</Kind>
<Access>
<Access.Order>
- <AccessModifier>Private</AccessModifier>
- <AccessModifier>PrivateProtected</AccessModifier>
- <AccessModifier>Protected</AccessModifier>
- <AccessModifier>ProtectedInternal</AccessModifier>
- <AccessModifier>Internal</AccessModifier>
<AccessModifier>Public</AccessModifier>
+ <AccessModifier>Internal</AccessModifier>
+ <AccessModifier>ProtectedInternal</AccessModifier>
+ <AccessModifier>Protected</AccessModifier>
+ <AccessModifier>PrivateProtected</AccessModifier>
+ <AccessModifier>Private</AccessModifier>
</Access.Order>
</Access>
+ <Static />
+ <Readonly />
<Name />
</Entry.SortBy>
</Entry>
</TypePattern>
</Patterns>
- <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
- <Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" />
- <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
- <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
- False
- HINT
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 90f739e..0e53b79 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,65 @@
-# ns-ext
\ No newline at end of file
+# 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();
+
+ Console.WriteLine(person.Json());
+ }
+}
+```
+
+### Output
+
+```json
+{"name":"Jason","age":30}
+```
\ No newline at end of file
diff --git a/README.zh-CN.md b/README.zh-CN.md
new file mode 100644
index 0000000..127d239
--- /dev/null
+++ b/README.zh-CN.md
@@ -0,0 +1,65 @@
+# 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();
+
+ Console.WriteLine(person.Json());
+ }
+}
+```
+
+### 输出
+
+```json
+{"name":"Jason","age":30}
+```
\ No newline at end of file
diff --git a/StyleCopAnalyzers.ruleset b/StyleCopAnalyzers.ruleset
new file mode 100644
index 0000000..f76edfe
--- /dev/null
+++ b/StyleCopAnalyzers.ruleset
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.cake b/build.cake
index ca99a64..1c37c0b 100644
--- a/build.cake
+++ b/build.cake
@@ -1,6 +1,6 @@
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
-var pkgOutPath = $"./build/NSExt/pkg/{configuration}";
+var pkgOutPath = $"./dist/NSExt/pkg/{configuration}";
////////////////////////////////////////////////////////////////
// Tasks
@@ -13,7 +13,7 @@ Task("Clean")
Task("Build")
.IsDependentOn("Clean")
- .Does(context =>
+ .Does(context =>
{
DotNetBuild("./NSExt.sln", new DotNetBuildSettings {
Configuration = configuration,
@@ -26,7 +26,7 @@ Task("Build")
Task("Test")
.IsDependentOn("Build")
- .Does(context =>
+ .Does(context =>
{
DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
Configuration = configuration,
@@ -49,7 +49,7 @@ Task("Test")
Task("Package")
.IsDependentOn("Build")
- .Does(context =>
+ .Does(context =>
{
context.DotNetPack("./NSExt.sln", new DotNetPackSettings {
Configuration = configuration,
@@ -64,7 +64,7 @@ Task("Package")
Task("Publish-GitHub")
.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
.IsDependentOn("Package")
- .Does(context =>
+ .Does(context =>
{
var apiKey = Argument("github-key", null);
if(string.IsNullOrWhiteSpace(apiKey)) {
@@ -73,10 +73,10 @@ Task("Publish-GitHub")
// Publish to GitHub Packages
var exitCode = 0;
- foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
+ foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
{
context.Information("Publishing {0}...", file.GetFilename().FullPath);
- exitCode += StartProcess("dotnet",
+ exitCode += StartProcess("dotnet",
new ProcessSettings {
Arguments = new ProcessArgumentBuilder()
.Append("gpr")
@@ -87,7 +87,7 @@ Task("Publish-GitHub")
);
}
- if(exitCode != 0)
+ if(exitCode != 0)
{
throw new CakeException("Could not push GitHub packages.");
}
@@ -96,7 +96,7 @@ Task("Publish-GitHub")
Task("Publish-NuGet")
// .WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
.IsDependentOn("Package")
- .Does(context =>
+ .Does(context =>
{
var apiKey = Argument("nuget-key", null);
if(string.IsNullOrWhiteSpace(apiKey)) {
@@ -104,7 +104,7 @@ Task("Publish-NuGet")
}
// Publish to GitHub Packages
- foreach(var file in context.GetFiles($"{pkgOutPath}/*.*nupkg"))
+ foreach(var file in context.GetFiles($"{pkgOutPath}/*.*nupkg"))
{
context.Information("Publishing {0}...", file.GetFilename().FullPath);
DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings
diff --git a/dotnet-tools.json b/dotnet-tools.json
index 55de44c..1158904 100644
--- a/dotnet-tools.json
+++ b/dotnet-tools.json
@@ -2,6 +2,5 @@
"version": 1,
"isRoot": true,
"tools": {
-
}
}
\ No newline at end of file
diff --git a/git-clean.ps1 b/git-clean.cmd
similarity index 100%
rename from git-clean.ps1
rename to git-clean.cmd
diff --git a/push2nuget.ps1 b/push2nuget.ps1
index 13df55a..24d0798 100644
--- a/push2nuget.ps1
+++ b/push2nuget.ps1
@@ -1,5 +1,5 @@
Param(
- # Nuget APIKey
+# Nuget APIKey
[string] $apikey
)
@@ -12,13 +12,13 @@ if ($apikey -eq $null -or $apikey -eq "")
rm -r ./build/nupkgs
dotnet build -c Release
$files = Get-ChildItem -Path ./build/nupkgs/ -Filter *.nupkg
-foreach($file in $files)
+foreach ($file in $files)
{
dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
nuget add $file.fullName -source d:\nuget-pkg
}
$files = Get-ChildItem -Path ./build/nupkgs/ -Filter *.snupkg
-foreach($file in $files)
+foreach ($file in $files)
{
dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
nuget add $file.fullName -source d:\nuget-pkg
diff --git a/src/Extensions/ByteExtensions.cs b/src/Extensions/ByteExtensions.cs
index 0252e34..fcf562c 100644
--- a/src/Extensions/ByteExtensions.cs
+++ b/src/Extensions/ByteExtensions.cs
@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
+///
+/// ByteExtensions
+///
public static class ByteExtensions
{
///
@@ -36,17 +39,16 @@ public static class ByteExtensions
///
/// 将字节数组转换成16进制字符串
///
- ///
+ /// me
/// 是否大写
/// 字节间分隔符
/// 分隔符跳跃字节数
- ///
public static string String(this IEnumerable me, bool upperCase = true, string splitShar = ""
, int splitInterval = 1)
{
var sb = new StringBuilder();
var i = 0;
- foreach (var c in me.Select(x => x.ToString(upperCase ? "X2" : "x2"))) {
+ foreach (var c in me.Select(x => x.ToString(upperCase ? "X2" : "x2", CultureInfo.InvariantCulture))) {
if (i++ % splitInterval == 0) {
sb.Append(splitShar);
}
diff --git a/src/Extensions/CharExtensions.cs b/src/Extensions/CharExtensions.cs
index 319cf91..3d5438a 100644
--- a/src/Extensions/CharExtensions.cs
+++ b/src/Extensions/CharExtensions.cs
@@ -1,12 +1,13 @@
namespace NSExt.Extensions;
+///
+/// CharExtensions
+///
public static class CharExtensions
{
///
/// 是否数字或大小写字母
///
- ///
- ///
public static bool IsAsciiLetterOrDigit(this char me)
{
return (((uint)me - 'A') & ~0x20) < 26 || (uint)me - '0' < 10;
@@ -15,8 +16,6 @@ public static class CharExtensions
///
/// 是否base64字符
///
- ///
- ///
public static bool IsBase64Character(this char me)
{
return IsAsciiLetterOrDigit(me) || me is '+' or '/' or '=';
diff --git a/src/Extensions/DateTimeExtensions.cs b/src/Extensions/DateTimeExtensions.cs
index 2e904b2..ac8cb43 100644
--- a/src/Extensions/DateTimeExtensions.cs
+++ b/src/Extensions/DateTimeExtensions.cs
@@ -1,27 +1,28 @@
+// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
+#pragma warning disable SA1300
+#pragma warning disable IDE1006
namespace NSExt.Extensions;
+///
+/// DateTimeExtensions
+///
public static class DateTimeExtensions
{
///
- /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串,如2秒以前,3天以前
+ /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串, 如2秒以前, 3天以前
///
/// 时间对象
/// 字符串
public static string TimeAgo(this DateTime me)
{
var ts = DateTime.Now - me;
- if (ts.Days > 0) return ts.Days + "天前";
-
- if (ts.Hours > 0) return ts.Hours + "小时前";
-
- if (ts.Minutes > 0) return ts.Minutes + "分钟前";
-
- return ts.Seconds + "秒前";
+ return ts.Days > 0 ? ts.Days + "天前" :
+ ts.Hours > 0 ? ts.Hours + "小时前" :
+ ts.Minutes > 0 ? ts.Minutes + "分钟前" : ts.Seconds + "秒前";
}
-
///
/// 指定时间的世界协调时的unix时间戳形式
///
@@ -35,55 +36,64 @@ public static class DateTimeExtensions
///
/// 指定时间的世界协调时的unix时间戳形式(毫秒)
///
- ///
- ///
public static long TimeUnixUtcMs(this DateTime me)
{
return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000;
}
-
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyy_MM
+ ///
public static string yyyy_MM(this DateTime me)
{
- return me.ToString("yyyy-MM");
+ return me.ToString("yyyy-MM", CultureInfo.InvariantCulture);
}
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyy_MM_dd
+ ///
public static string yyyy_MM_dd(this DateTime me)
{
- return me.ToString("yyyy-MM-dd");
+ return me.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyy_MM_dd_HH_mm
+ ///
public static string yyyy_MM_dd_HH_mm(this DateTime me)
{
- return me.ToString("yyyy-MM-dd HH:mm");
+ return me.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
}
-
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyy_MM_dd_HH_mm_ss
+ ///
public static string yyyy_MM_dd_HH_mm_ss(this DateTime me)
{
- return me.ToString("yyyy-MM-dd HH:mm:ss");
+ return me.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
}
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyy_MM_dd_HH_mm_ss_fff
+ ///
public static string yyyy_MM_dd_HH_mm_ss_fff(this DateTime me)
{
- return me.ToString("yyyy-MM-dd HH:mm:ss.fff");
+ return me.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
}
-
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyyMM
+ ///
public static string yyyyMM(this DateTime me)
{
- return me.ToString("yyyyMM");
+ return me.ToString("yyyyMM", CultureInfo.InvariantCulture);
}
- // ReSharper disable once InconsistentNaming
+ ///
+ /// yyyyMMdd
+ ///
public static string yyyyMMdd(this DateTime me)
{
- return me.ToString("yyyyMMdd");
+ return me.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
}
}
\ No newline at end of file
diff --git a/src/Extensions/DbCommandExtensions.cs b/src/Extensions/DbCommandExtensions.cs
index caaf214..d1a4e75 100644
--- a/src/Extensions/DbCommandExtensions.cs
+++ b/src/Extensions/DbCommandExtensions.cs
@@ -1,28 +1,46 @@
namespace NSExt.Extensions;
+///
+/// DbCommandExtensions
+///
public static class DbCommandExtensions
{
///
/// 格式化参数拼接成完整的SQL语句
///
- ///
public static string ParameterFormat(this DbCommand me)
{
//var aa = pars.ToDictionary(it => it.ParameterName, it => it.Value);
var sql = me.CommandText;
//应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @TenantId1 @TenantId10
- for (var i = me.Parameters.Count - 1; i >= 0; i--)
+ for (var i = me.Parameters.Count - 1; i >= 0; i--) {
sql = me.Parameters[i].DbType switch {
DbType.String or DbType.DateTime or DbType.Date or DbType.Time or DbType.DateTime2
or DbType.DateTimeOffset or DbType.Guid or DbType.VarNumeric or DbType.AnsiStringFixedLength
- or DbType.AnsiString
- or DbType.StringFixedLength =>
- sql.Replace(me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'")
- , DbType.Boolean => sql.Replace(me.Parameters[i].ParameterName
- , Convert.ToBoolean(me.Parameters[i].Value) ? "1" : "0")
- , _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString())
+ or DbType.AnsiString or DbType.StringFixedLength => sql.Replace( //
+ me.Parameters[i].ParameterName, "'" + me.Parameters[i].Value + "'")
+ , DbType.Boolean => sql.Replace( //
+ me.Parameters[i].ParameterName
+ , Convert.ToBoolean(me.Parameters[i].Value, CultureInfo.InvariantCulture) ? "1" : "0")
+ , DbType.Binary => throw new NotImplementedException()
+ , DbType.Byte => throw new NotImplementedException()
+ , DbType.Currency => throw new NotImplementedException()
+ , DbType.Decimal => throw new NotImplementedException()
+ , DbType.Double => throw new NotImplementedException()
+ , DbType.Int16 => throw new NotImplementedException()
+ , DbType.Int32 => throw new NotImplementedException()
+ , DbType.Int64 => throw new NotImplementedException()
+ , DbType.Object => throw new NotImplementedException()
+ , DbType.SByte => throw new NotImplementedException()
+ , DbType.Single => throw new NotImplementedException()
+ , DbType.UInt16 => throw new NotImplementedException()
+ , DbType.UInt32 => throw new NotImplementedException()
+ , DbType.UInt64 => throw new NotImplementedException()
+ , DbType.Xml => throw new NotImplementedException()
+ , _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString())
};
+ }
return sql;
}
diff --git a/src/Extensions/DecimalExtensions.cs b/src/Extensions/DecimalExtensions.cs
index 3695204..6dfd32a 100644
--- a/src/Extensions/DecimalExtensions.cs
+++ b/src/Extensions/DecimalExtensions.cs
@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
+///
+/// DecimalExtensions
+///
public static class DecimalExtensions
{
///
diff --git a/src/Extensions/EnumExtensions.cs b/src/Extensions/EnumExtensions.cs
index a7e5827..80ae7bd 100644
--- a/src/Extensions/EnumExtensions.cs
+++ b/src/Extensions/EnumExtensions.cs
@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
+///
+/// EnumExtensions
+///
public static class EnumExtensions
{
///
@@ -12,6 +15,6 @@ public static class EnumExtensions
var t = e.GetType();
var fi = t.GetField(Enum.GetName(t, e)!);
var attrs = (DescriptionAttribute[])fi!.GetCustomAttributes(typeof(DescriptionAttribute), false);
- return (attrs.Length != 0 ? attrs[0].Description : Enum.GetName(t, e)) ?? "";
+ return (attrs.Length != 0 ? attrs[0].Description : Enum.GetName(t, e)) ?? string.Empty;
}
}
\ No newline at end of file
diff --git a/src/Extensions/EnumerableExtensions.cs b/src/Extensions/EnumerableExtensions.cs
index 067f057..ebebe01 100644
--- a/src/Extensions/EnumerableExtensions.cs
+++ b/src/Extensions/EnumerableExtensions.cs
@@ -1,13 +1,13 @@
namespace NSExt.Extensions;
+///
+/// EnumerableExtensions
+///
public static class EnumerableExtensions
{
///
/// 将列表转成分隔符分隔的字符串
///
- ///
- ///
- ///
public static string Join(this IEnumerable
/// 要加密的串
/// 密钥
- /// 指定要用于加密的块密码模式。
- /// 指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型。
- ///
- public static string AesDe(this string me, string key, CipherMode cipherMode = CipherMode.ECB
- , PaddingMode paddingMode = PaddingMode.PKCS7)
+ public static string AesDe(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
@@ -87,7 +84,6 @@ public static partial class StringExtensions
///
/// 将易于web传输的base64web字符串转换为原生base64
///
- ///
/// 原生base64
public static string Base64Sys(this string me)
{
@@ -97,7 +93,6 @@ public static partial class StringExtensions
///
/// 将原生base64字符串转换成易于web传输的字符串
///
- ///
/// 易于web传输的字符串
public static string Base64Web(this string me)
{
@@ -184,10 +179,8 @@ public static partial class StringExtensions
///
/// 将字符串转换成枚举对象
///
- ///
- ///
- ///
- public static T Enum(this string name) where T : Enum
+ public static T Enum(this string name)
+ where T : Enum
{
return (T)System.Enum.Parse(typeof(T), name, true);
}
@@ -195,11 +188,8 @@ public static partial class StringExtensions
///
/// 将字符串转换成枚举对象
///
- ///
- ///
- ///
- ///
- public static T EnumTry(this string name, T def) where T : Enum
+ public static T EnumTry(this string name, T def)
+ where T : Enum
{
return !System.Enum.TryParse(typeof(T), name, out var ret) ? def : (T)ret;
}
@@ -218,7 +208,6 @@ public static partial class StringExtensions
/// 将字符串转为guid
///
/// 字符串
- ///
public static Guid Guid(this string me)
{
return System.Guid.Parse(me);
@@ -229,7 +218,6 @@ public static partial class StringExtensions
///
/// 字符串
/// 转换失败的返回值
- ///
public static Guid Guid(this string me, Guid def)
{
return System.Guid.TryParse(me, out var ret) ? ret : def;
@@ -245,7 +233,6 @@ public static partial class StringExtensions
{
return e.GetBytes(me);
}
- //public static byte[] TextHex(this string me,)
///
/// 将字符串转换成字节数组形式
@@ -260,7 +247,7 @@ public static partial class StringExtensions
///
/// 对一个字符串进行sha1 hash运算
///
- /// 对一个字符串进行sha1 hash运算
+ /// me
/// 密钥
/// 使用的编码
/// hash摘要的16进制文本形式(无连字符小写)
@@ -276,8 +263,6 @@ public static partial class StringExtensions
///
/// html编码
///
- ///
- ///
public static string Html(this string me)
{
return HttpUtility.HtmlEncode(me);
@@ -338,8 +323,6 @@ public static partial class StringExtensions
///
/// ipv4格式转int32格式
///
- ///
- ///
public static int IpV4ToInt32(this string me)
{
return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0);
@@ -349,7 +332,6 @@ public static partial class StringExtensions
/// 是否base64字符串
///
/// 字符串
- ///
public static bool IsBase64String(this string me)
{
// 一个合法的Base64,有着以下特征:
@@ -375,15 +357,9 @@ public static partial class StringExtensions
///
/// 中文姓名打马赛克
///
- ///
- ///
public static string MaskChineseName(this string me)
{
- if (me.Length == 2) {
- return "*" + me[1..];
- }
-
- return me[..1] + "*" + me[^1..];
+ return me.Length == 2 ? "*" + me[1..] : me[..1] + "*" + me[^1..];
}
///
@@ -393,7 +369,7 @@ public static partial class StringExtensions
/// 掩码后的手机号
public static string MaskMobile(this string me)
{
- return new Regex(@"^(\d{3})\d{4}(\d{4})$").Replace(me, "$1****$2");
+ return RegexMobile().Replace(me, "$1****$2");
}
///
@@ -404,8 +380,7 @@ public static partial class StringExtensions
/// hash摘要的16进制文本形式(无连字符小写)
public static string Md5(this string me, Encoding e)
{
- using var md5 = MD5.Create();
- return BitConverter.ToString(md5.ComputeHash(e.GetBytes(me)))
+ return BitConverter.ToString(MD5.HashData(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
@@ -424,8 +399,6 @@ public static partial class StringExtensions
///
/// null或空白字符
///
- ///
- ///
public static bool NullOrWhiteSpace(this string me)
{
return string.IsNullOrWhiteSpace(me);
@@ -471,17 +444,15 @@ public static partial class StringExtensions
/// 处理之后的字符串
public static string RemoveHtmlTag(this string me)
{
- return new Regex(@"<[^>]*>").Replace(me, "");
+ return RegexHtmlTag().Replace(me, string.Empty);
}
///
/// 删除换行符
///
- ///
- ///
public static string RemoveWrapped(this string me)
{
- return me.Replace("\r", "").Replace("\n", "");
+ return me.Replace("\r", string.Empty).Replace("\n", string.Empty);
}
///
@@ -492,8 +463,7 @@ public static partial class StringExtensions
/// hash摘要的16进制文本形式(无连字符小写)
public static string Sha1(this string me, Encoding e)
{
- using var sha1 = SHA1.Create();
- return BitConverter.ToString(sha1.ComputeHash(e.GetBytes(me)))
+ return BitConverter.ToString(SHA1.HashData(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
@@ -501,20 +471,14 @@ public static partial class StringExtensions
///
/// 蛇形命名
///
- ///
- ///
public static string Snakecase(this string me)
{
- return Regex.Replace(me, "([A-Z])", "-$1").ToLower().TrimStart('-');
+ return RegexUpperCaseLetter().Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
}
///
/// 截取指定长度的字符串,代替substring
///
- ///
- ///
- ///
- ///
public static string Sub(this string me, int startIndex, int length)
{
if (startIndex + length > me.Length) {
@@ -527,8 +491,6 @@ public static partial class StringExtensions
///
/// 纯文本字符串转html
///
- ///
- ///
public static string Text2Html(this string me)
{
return $"{me}
";
@@ -537,28 +499,22 @@ public static partial class StringExtensions
///
/// 将连续多个空格替换成一个空格
///
- ///
- ///
public static string TrimSpaces(this string me)
{
var ret = me.Replace(" ", " ");
+
// ReSharper disable once TailRecursiveCall
return ret == me ? ret : ret.TrimSpaces();
}
///
- /// 将\ux0000 、 %u0000 、 编码转换成可读字符串
+ /// 将\ux0000 、 %u0000 、 � 编码转换成可读字符串
///
- ///
- ///
public static string UnicodeDe(this string me)
{
const string replacement = "$1;";
- if (me.Contains(@"\u")) {
- return RegexBacksLantUnicode().Replace(me, replacement).HtmlDe();
- }
-
- return me.Contains(@"%u") ? RegexPercentUnicode().Replace(me, replacement).HtmlDe() : me.HtmlDe();
+ return me.Contains(@"\u") ? RegexBacksLantUnicode().Replace(me, replacement).HtmlDe() :
+ me.Contains(@"%u") ? RegexPercentUnicode().Replace(me, replacement).HtmlDe() : me.HtmlDe();
}
///
@@ -599,6 +555,15 @@ public static partial class StringExtensions
[GeneratedRegex("\\\\u([a-fA-F0-9]{4})")]
private static partial Regex RegexBacksLantUnicode();
+ [GeneratedRegex("<[^>]*>")]
+ private static partial Regex RegexHtmlTag();
+
+ [GeneratedRegex("^(\\d{3})\\d{4}(\\d{4})$")]
+ private static partial Regex RegexMobile();
+
[GeneratedRegex("\\\\u([a-fA-F0-9]{4})")]
private static partial Regex RegexPercentUnicode();
+
+ [GeneratedRegex("([A-Z])")]
+ private static partial Regex RegexUpperCaseLetter();
}
\ No newline at end of file
diff --git a/src/Extensions/TypeExtensions.cs b/src/Extensions/TypeExtensions.cs
index a8739d0..ea897bc 100644
--- a/src/Extensions/TypeExtensions.cs
+++ b/src/Extensions/TypeExtensions.cs
@@ -1,13 +1,13 @@
namespace NSExt.Extensions;
+///
+/// TypeExtensions
+///
public static class TypeExtensions
{
///
/// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。
///
- ///
- ///
- ///
public static IEnumerable GetCustomAttributesIncludingBaseInterfaces(this Type me)
{
var attributeType = typeof(T);
diff --git a/src/Extensions/UriExtensions.cs b/src/Extensions/UriExtensions.cs
index 8b8bb43..6f9377a 100644
--- a/src/Extensions/UriExtensions.cs
+++ b/src/Extensions/UriExtensions.cs
@@ -1,12 +1,13 @@
namespace NSExt.Extensions;
+///
+/// UriExtensions
+///
public static class UriExtensions
{
///
/// 移除url的Scheme
///
- ///
- ///
public static string RemoveScheme(this Uri me)
{
return "//" + me.Authority + me.PathAndQuery;
diff --git a/src/GlobalUsings.cs b/src/GlobalUsings.cs
index a5091a5..4893fbf 100644
--- a/src/GlobalUsings.cs
+++ b/src/GlobalUsings.cs
@@ -1,9 +1,9 @@
+global using System.ComponentModel;
global using System.Data;
global using System.Data.Common;
-global using System.Runtime.CompilerServices;
-global using Microsoft.Extensions.Logging;
global using System.Globalization;
+global using System.Runtime.CompilerServices;
global using System.Text;
global using System.Text.RegularExpressions;
global using System.Web;
-global using System.ComponentModel;
\ No newline at end of file
+global using Microsoft.Extensions.Logging;
\ No newline at end of file
diff --git a/src/NSExt.csproj b/src/NSExt.csproj
index 88315e6..1196f66 100644
--- a/src/NSExt.csproj
+++ b/src/NSExt.csproj
@@ -1,7 +1,8 @@
- net7.0
+ net7.0
+ true
@@ -12,5 +13,5 @@
-
+
\ No newline at end of file
diff --git a/stylecop.json b/stylecop.json
new file mode 100644
index 0000000..ae79eec
--- /dev/null
+++ b/stylecop.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "useTabs": false,
+ "indentationSize": 4
+ }
+ }
+}
\ No newline at end of file