From 70f5870b601bd581dccfbda09e858d63c6b769fe Mon Sep 17 00:00:00 2001 From: taoke Date: Fri, 15 Jul 2022 17:04:46 +0800 Subject: [PATCH] init --- .gitattributes | 63 +++++ .gitignore | 23 ++ doc/README.md | 1 + lib/README.md | 1 + res/README.md | 1 + script/README.md | 1 + src/.editorconfig | 89 +++++++ src/NSExt.sln | 16 ++ src/NSExt.sln.DotSettings | 95 ++++++++ src/NSExt/ByteExtensions.cs | 34 +++ src/NSExt/DateTimeExtensions.cs | 81 +++++++ src/NSExt/DecimalExtensions.cs | 22 ++ src/NSExt/EnumExtensions.cs | 25 ++ src/NSExt/EnumerableExtensions.cs | 32 +++ src/NSExt/GenericExtensions.cs | 49 ++++ src/NSExt/IntExtensions.cs | 37 +++ src/NSExt/LoggerExtensions.cs | 76 ++++++ src/NSExt/LongExtensions.cs | 33 +++ src/NSExt/NSExt.csproj | 15 ++ src/NSExt/ObjectExtensions.cs | 23 ++ src/NSExt/StringExtensions.cs | 390 ++++++++++++++++++++++++++++++ src/NSExt/UriExtensions.cs | 20 ++ src/README.md | 1 + 23 files changed, 1128 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 doc/README.md create mode 100644 lib/README.md create mode 100644 res/README.md create mode 100644 script/README.md create mode 100644 src/.editorconfig create mode 100644 src/NSExt.sln create mode 100644 src/NSExt.sln.DotSettings create mode 100644 src/NSExt/ByteExtensions.cs create mode 100644 src/NSExt/DateTimeExtensions.cs create mode 100644 src/NSExt/DecimalExtensions.cs create mode 100644 src/NSExt/EnumExtensions.cs create mode 100644 src/NSExt/EnumerableExtensions.cs create mode 100644 src/NSExt/GenericExtensions.cs create mode 100644 src/NSExt/IntExtensions.cs create mode 100644 src/NSExt/LoggerExtensions.cs create mode 100644 src/NSExt/LongExtensions.cs create mode 100644 src/NSExt/NSExt.csproj create mode 100644 src/NSExt/ObjectExtensions.cs create mode 100644 src/NSExt/StringExtensions.cs create mode 100644 src/NSExt/UriExtensions.cs create mode 100644 src/README.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b8949dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +bin +obj +bin\log +packages +_gsdata_ +_ReSharper* +TestResults +app_data +*.suo +*.user +*.log +*.pubxml +*.publish.xml +.svn +.vs +*.dbmdl +*.jfm +*.exe +.idea +node_modules +dist +/src/Ddf/Ddf.App/ddf-dcloud/unpackage/cache +/src/Ddf/Ddf.App/ddf-dcloud/unpackage/release/apk diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/doc/README.md @@ -0,0 +1 @@ + diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/README.md @@ -0,0 +1 @@ + diff --git a/res/README.md b/res/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/res/README.md @@ -0,0 +1 @@ + diff --git a/script/README.md b/script/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/README.md @@ -0,0 +1 @@ + diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 0000000..60c2173 --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,89 @@ +[*.{appxmanifest,asax,ascx,aspx,axaml,axml,build,config,cs,cshtml,csproj,css,dbml,discomap,dtd,htm,html,js,json,jsproj,jsx,lsproj,master,njsproj,nuspec,paml,proj,props,proto,razor,resjson,resw,resx,skin,StyleCop,targets,tasks,ts,tsx,vb,vbproj,xaml,xamlx,xml,xoml,xsd}] +indent_style = space +indent_size = space +tab_width = 4 + +[*] + +# Microsoft .NET properties +csharp_indent_braces = false +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = local_functions, methods, types +csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion +csharp_style_var_elsewhere = true:suggestion +csharp_style_var_for_built_in_types = true:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none +dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none +dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion + +# ReSharper inspection severities +resharper_arrange_redundant_parentheses_highlighting = hint +resharper_arrange_this_qualifier_highlighting = hint +resharper_arrange_type_member_modifiers_highlighting = hint +resharper_arrange_type_modifiers_highlighting = hint +resharper_built_in_type_reference_style_for_member_access_highlighting = hint +resharper_built_in_type_reference_style_highlighting = hint +resharper_redundant_base_qualifier_highlighting = warning +resharper_suggest_var_or_type_built_in_types_highlighting = hint +resharper_suggest_var_or_type_elsewhere_highlighting = hint +resharper_suggest_var_or_type_simple_types_highlighting = hint + +# ReSharper properties +resharper_align_first_arg_by_paren = true +resharper_align_linq_query = true +resharper_align_multiline_argument = true +resharper_align_multiline_array_and_object_initializer = false +resharper_align_multiline_calls_chain = true +resharper_align_multiline_expression = true +resharper_align_multiline_extends_list = true +resharper_align_multiline_for_stmt = true +resharper_align_multiline_property_pattern = true +resharper_align_multiline_switch_expression = true +resharper_align_multline_type_parameter_constrains = true +resharper_align_multline_type_parameter_list = true +resharper_align_tuple_components = true +resharper_csharp_align_multiline_parameter = true +resharper_csharp_align_multiple_declaration = true +resharper_csharp_empty_block_style = together +resharper_csharp_indent_size = 4 +resharper_csharp_indent_style = space +resharper_csharp_insert_final_newline = true +resharper_csharp_max_line_length = 120 +resharper_csharp_stick_comment = false +resharper_csharp_tab_width = 4 +resharper_csharp_wrap_arguments_style = chop_if_long +resharper_csharp_wrap_before_comma = false +resharper_csharp_wrap_chained_method_calls = chop_if_long +resharper_csharp_wrap_extends_list_style = chop_if_long +resharper_csharp_wrap_parameters_style = chop_if_long +resharper_indent_anonymous_method_block = true +resharper_indent_nested_fixed_stmt = true +resharper_indent_nested_foreach_stmt = true +resharper_indent_nested_for_stmt = true +resharper_indent_nested_lock_stmt = true +resharper_indent_nested_usings_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_keep_existing_linebreaks = false +resharper_max_initializer_elements_on_line = 1 +resharper_outdent_commas = true +resharper_outdent_dots = true +resharper_wrap_array_initializer_style = chop_always +resharper_wrap_before_comma = false +resharper_wrap_object_and_collection_initializer_style = chop_always + +[*.cs] +indent_style = space +indent_size = 4 +tab_width = 4 diff --git a/src/NSExt.sln b/src/NSExt.sln new file mode 100644 index 0000000..25a57b6 --- /dev/null +++ b/src/NSExt.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "NSExt\NSExt.csproj", "{54814D1B-C587-4D90-A7BE-4BE1E170D5FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/NSExt.sln.DotSettings b/src/NSExt.sln.DotSettings new file mode 100644 index 0000000..bc7c36a --- /dev/null +++ b/src/NSExt.sln.DotSettings @@ -0,0 +1,95 @@ + + DO_NOT_SHOW + DO_NOT_SHOW + <?xml version="1.0" encoding="utf-16"?><Profile name="Built-in: Full Cleanup With File Header"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CppAddTypenameTemplateKeywords>True</CppAddTypenameTemplateKeywords><CppRemoveCastDescriptor>True</CppRemoveCastDescriptor><CppRemoveElseKeyword>True</CppRemoveElseKeyword><CppShortenQualifiedName>True</CppShortenQualifiedName><CppDeleteRedundantSpecifier>True</CppDeleteRedundantSpecifier><CppRemoveStatement>True</CppRemoveStatement><CppDeleteRedundantTypenameTemplateKeywords>True</CppDeleteRedundantTypenameTemplateKeywords><CppCStyleToStaticCastDescriptor>True</CppCStyleToStaticCastDescriptor><CppReplaceExpressionWithBooleanConst>True</CppReplaceExpressionWithBooleanConst><CppMakeIfConstexpr>True</CppMakeIfConstexpr><CppMakePostfixOperatorPrefix>True</CppMakePostfixOperatorPrefix><CppChangeSmartPointerToMakeFunction>True</CppChangeSmartPointerToMakeFunction><CppReplaceThrowWithRethrowFix>True</CppReplaceThrowWithRethrowFix><CppTypeTraitAliasDescriptor>True</CppTypeTraitAliasDescriptor><CppReplaceExpressionWithNullptr>True</CppReplaceExpressionWithNullptr><CppReplaceTieWithStructuredBindingDescriptor>True</CppReplaceTieWithStructuredBindingDescriptor><CppUseAssociativeContainsDescriptor>True</CppUseAssociativeContainsDescriptor><CppUseEraseAlgorithmDescriptor>True</CppUseEraseAlgorithmDescriptor><CppCodeStyleCleanupDescriptor ArrangeBraces="True" ArrangeAuto="True" ArrangeFunctionDeclarations="True" ArrangeNestedNamespaces="True" ArrangeTypeAliases="True" ArrangeCVQualifiers="True" ArrangeSlashesInIncludeDirectives="True" ArrangeOverridingFunctions="True" SortIncludeDirectives="True" SortMemberInitializers="True" /><CppReformatCode>True</CppReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" ArrangeArgumentsStyle="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><RemoveCodeRedundanciesVB>True</RemoveCodeRedundanciesVB><Xaml.RedundantFreezeAttribute>True</Xaml.RedundantFreezeAttribute><Xaml.RemoveRedundantModifiersAttribute>True</Xaml.RemoveRedundantModifiersAttribute><Xaml.RemoveRedundantNameAttribute>True</Xaml.RemoveRedundantNameAttribute><Xaml.RemoveRedundantResource>True</Xaml.RemoveRedundantResource><Xaml.RemoveRedundantCollectionProperty>True</Xaml.RemoveRedundantCollectionProperty><Xaml.RemoveRedundantAttachedPropertySetter>True</Xaml.RemoveRedundantAttachedPropertySetter><Xaml.RemoveRedundantStyledValue>True</Xaml.RemoveRedundantStyledValue><Xaml.RemoveRedundantNamespaceAlias>True</Xaml.RemoveRedundantNamespaceAlias><Xaml.RemoveForbiddenResourceName>True</Xaml.RemoveForbiddenResourceName><Xaml.RemoveRedundantGridDefinitionsAttribute>True</Xaml.RemoveRedundantGridDefinitionsAttribute><Xaml.RemoveRedundantUpdateSourceTriggerAttribute>True</Xaml.RemoveRedundantUpdateSourceTriggerAttribute><Xaml.RemoveRedundantBindingModeAttribute>True</Xaml.RemoveRedundantBindingModeAttribute><Xaml.RemoveRedundantGridSpanAttribut>True</Xaml.RemoveRedundantGridSpanAttribut><XMLReformatCode>True</XMLReformatCode><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><HtmlReformatCode>True</HtmlReformatCode><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><IDEA_SETTINGS>&lt;profile version="1.0"&gt; + &lt;option name="myName" value="Built-in: Full Cleanup With File Header" /&gt; +&lt;/profile&gt;</IDEA_SETTINGS><RIDER_SETTINGS>&lt;profile&gt; + &lt;Language id="CSS"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;/Language&gt; + &lt;Language id="EditorConfig"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="HTML"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; + &lt;/Language&gt; + &lt;Language id="HTTP Request"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Handlebars"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Ini"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="JSON"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Jade"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="JavaScript"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; + &lt;/Language&gt; + &lt;Language id="Markdown"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Properties"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="RELAX-NG"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="SQL"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="XML"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; + &lt;/Language&gt; + &lt;Language id="yaml"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; +&lt;/profile&gt;</RIDER_SETTINGS><CSUpdateFileHeader>True</CSUpdateFileHeader><CppUpdateFileHeader>True</CppUpdateFileHeader></Profile> + <?xml version="1.0" encoding="utf-16"?> +<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> + <TypePattern DisplayName="Type Pattern"> + <Entry DisplayName="Entry"> + <Entry.Match> + <Kind Is="Property" /> + </Entry.Match> + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </TypePattern> +</Patterns> + DI + DO + IV + <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + True + @program: $PROJECT$ +@file: $FILENAME$ +@author: tao ke +@mailto: taokeu@gmail.com +@created: $CREATED_MONTH$/$CREATED_DAY$/$CREATED_YEAR$ $CREATED_TIME$ + + True + True + True + True + True + True + True + True + True + True \ No newline at end of file diff --git a/src/NSExt/ByteExtensions.cs b/src/NSExt/ByteExtensions.cs new file mode 100644 index 0000000..a72fcdb --- /dev/null +++ b/src/NSExt/ByteExtensions.cs @@ -0,0 +1,34 @@ +// @program: NSExt +// @file: ByteExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +using System.Text; + +namespace NSExt; + +public static class ByteExtensions +{ + /// + /// base64编码 + /// + /// 待编码的字节数组 + /// 编码后的base64字符串 + public static string Base64(this byte[] me) + { + return Convert.ToBase64String(me); + } + + + /// + /// 将字节数组解码成字符串 + /// + /// 字节数组 + /// 字符串使用的编码方式 + /// 解码后的原始字符串 + public static string HexDe(this byte[] me, Encoding e) + { + return e.GetString(me); + } +} diff --git a/src/NSExt/DateTimeExtensions.cs b/src/NSExt/DateTimeExtensions.cs new file mode 100644 index 0000000..22a33d5 --- /dev/null +++ b/src/NSExt/DateTimeExtensions.cs @@ -0,0 +1,81 @@ +// @program: NSExt +// @file: DateTimeExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +// ReSharper disable UnusedMember.Global + +namespace NSExt; + +public static class DateTimeExtensions +{ + /// + /// 将一个过去时间对象与当前时间相减转换成“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 + "秒前"; + } + + + /// + /// 指定时间的世界协调时的unix时间戳形式 + /// + /// 指定时间 + /// unix时间戳 + public static long TimeUnixUtc(this DateTime me) + { + return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000000; + } + + /// + /// 指定时间的世界协调时的unix时间戳形式(毫秒) + /// + /// + /// + public static long TimeUnixUtcMs(this DateTime me) + { + return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000; + } + + + // ReSharper disable once InconsistentNaming + public static string yyyyMM(this DateTime me) + { + return me.ToString("yyyy-MM"); + } + + // ReSharper disable once InconsistentNaming + public static string yyyyMMdd(this DateTime me) + { + return me.ToString("yyyy-MM-dd"); + } + + // ReSharper disable once InconsistentNaming + public static string yyyyMMddHHmm(this DateTime me) + { + return me.ToString("yyyy-MM-dd HH:mm"); + } + + + // ReSharper disable once InconsistentNaming + public static string yyyyMMddHHmmss(this DateTime me) + { + return me.ToString("yyyy-MM-dd HH:mm:ss"); + } + + public static string yyyyMMddHHmmssfff(this DateTime me) + { + return me.ToString("yyyy-MM-dd HH:mm:ss.fff"); + } +} diff --git a/src/NSExt/DecimalExtensions.cs b/src/NSExt/DecimalExtensions.cs new file mode 100644 index 0000000..d6fe176 --- /dev/null +++ b/src/NSExt/DecimalExtensions.cs @@ -0,0 +1,22 @@ +// @program: NSExt +// @file: DecimalExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +namespace NSExt; + +public static class DecimalExtensions +{ + /// + /// 四舍五入后的近似值 + /// + /// 数字 + /// 小数点位数 + /// 处理后的值 + public static decimal Round(this decimal me, int place) + { + var dec = Math.Round(me, place); + return dec; + } +} diff --git a/src/NSExt/EnumExtensions.cs b/src/NSExt/EnumExtensions.cs new file mode 100644 index 0000000..f3b7221 --- /dev/null +++ b/src/NSExt/EnumExtensions.cs @@ -0,0 +1,25 @@ +// @program: NSExt +// @file: EnumExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +using System.ComponentModel; + +namespace NSExt; + +public static class EnumExtensions +{ + /// + /// 获取枚举的description属性 + /// + /// 枚举对象 + /// description属性 + 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)) ?? ""; + } +} diff --git a/src/NSExt/EnumerableExtensions.cs b/src/NSExt/EnumerableExtensions.cs new file mode 100644 index 0000000..69462fa --- /dev/null +++ b/src/NSExt/EnumerableExtensions.cs @@ -0,0 +1,32 @@ +// @program: NSExt +// @file: EnumerableExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +namespace NSExt; + +public static class EnumerableExtensions +{ + /// + /// 将列表转成分隔符分隔的字符串 + /// + /// + /// + /// + public static string Join(this IEnumerable me, string separator) + { + return string.Join(separator, me); + } + + /// + /// 判断对象是否为null或不存在子元素(如果为集合对象) + /// + /// 对象类型 + /// 指定对象 + /// 空则返回true + public static bool NullOrEmpty(this IEnumerable me) + { + return me is null || !me.Any(); + } +} diff --git a/src/NSExt/GenericExtensions.cs b/src/NSExt/GenericExtensions.cs new file mode 100644 index 0000000..9d72599 --- /dev/null +++ b/src/NSExt/GenericExtensions.cs @@ -0,0 +1,49 @@ +// @program: NSExt +// @file: GenericExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +namespace NSExt; + +public static class GenericExtensions +{ + /// + /// 从指定的对象拷贝属性 + /// + /// 对象类型 + /// 拷贝目标 + /// 拷贝来源 + /// 需要处理的属性名 + /// True包含,false排除 + public static void CopyFrom(this T me, + T copyObj, + IList propNameList = null, + bool isIncludeOrExclude = false) + { + foreach (var p in me.GetType().GetProperties()) { + if (!p.CanWrite) 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); + } + } + + + /// + /// 判断是否与某对象相等 + /// + /// + /// + /// + /// + /// + public static T Is(this T me, T compare, T ret) where T : struct + { + return me.Equals(compare) ? ret : me; + } +} diff --git a/src/NSExt/IntExtensions.cs b/src/NSExt/IntExtensions.cs new file mode 100644 index 0000000..bdf71b7 --- /dev/null +++ b/src/NSExt/IntExtensions.cs @@ -0,0 +1,37 @@ +// @program: NSExt +// @file: IntExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +namespace NSExt; + +public static class IntExtensions +{ + /// + /// 判断枚举是否包含某个位 + /// + /// + /// + /// + /// + public static bool HasFlag(this int me, T flag) where T : Enum + { + return ((long)me).HasFlag(flag); + } + + /// + /// 生成随机数 + /// + /// 大于等于[0],小于[1] + /// + public static int Rand(this int[] me) + { + return new Random(Guid.NewGuid().GetHashCode()).Next(me[0], me[1]); + } + + public static string ToIpV4(this int me) + { + return string.Join(".", BitConverter.GetBytes(me).Reverse()); + } +} diff --git a/src/NSExt/LoggerExtensions.cs b/src/NSExt/LoggerExtensions.cs new file mode 100644 index 0000000..8bac709 --- /dev/null +++ b/src/NSExt/LoggerExtensions.cs @@ -0,0 +1,76 @@ +// @program: NSExt +// @file: LoggerExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +using System.Runtime.CompilerServices; +using Microsoft.Extensions.Logging; + +// ReSharper disable UnusedMember.Global + +namespace NSExt; + +public static class LoggerExtensions +{ + private static string CallerInfoMessage(object message, + string callerName, + string callerFilePath, + int callerLineNumber) + { + return + $"[{Thread.CurrentThread.ManagedThreadId}#{callerName}@{Path.GetFileName(callerFilePath)}:{callerLineNumber}] {message}"; + } + + public static void Debug(this ILogger me, + object message, + [CallerMemberName] string callerName = null, + [CallerFilePath] string callerFilePath = null, + [CallerLineNumber] int callerLineNumber = 0) + { + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + 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) + { + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + me.LogError(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + } + + public static void Fatal(this ILogger me, + object message, + [CallerMemberName] string callerName = null, + [CallerFilePath] string callerFilePath = null, + [CallerLineNumber] int callerLineNumber = 0) + { + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + } + + + public static void Info(this ILogger me, + object message, + [CallerMemberName] string callerName = null, + [CallerFilePath] string callerFilePath = null, + [CallerLineNumber] int callerLineNumber = 0) + { + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + 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) + { + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + me.LogWarning(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber)); + } +} diff --git a/src/NSExt/LongExtensions.cs b/src/NSExt/LongExtensions.cs new file mode 100644 index 0000000..f28cf5f --- /dev/null +++ b/src/NSExt/LongExtensions.cs @@ -0,0 +1,33 @@ +// @program: NSExt +// @file: LongExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +namespace NSExt; + +public static class LongExtensions +{ + /// + /// 判断枚举是否包含某个位 + /// + /// + /// + /// + /// + public static bool HasFlag(this long me, T flag) where T : Enum + { + var val = (long)(object)flag; + return (me & val) == val; + } + + /// + /// 1970毫秒数转换成日期对象 + /// + /// + /// + public static DateTime Time(this long msFrom1970) + { + return new DateTime(1970, 1, 1).AddMilliseconds(msFrom1970).ToLocalTime(); + } +} diff --git a/src/NSExt/NSExt.csproj b/src/NSExt/NSExt.csproj new file mode 100644 index 0000000..09804e6 --- /dev/null +++ b/src/NSExt/NSExt.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + + + + + + + + + + diff --git a/src/NSExt/ObjectExtensions.cs b/src/NSExt/ObjectExtensions.cs new file mode 100644 index 0000000..7dcc845 --- /dev/null +++ b/src/NSExt/ObjectExtensions.cs @@ -0,0 +1,23 @@ +// @program: NSExt +// @file: ObjectExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +using Newtonsoft.Json; + +namespace NSExt; + +public static class ObjectExtensions +{ + /// + /// 将一个对象序列化成json文本 + /// + /// 指定对象 + /// 是否格式化 + /// json文本 + public static string Json(this object me, bool format = false) + { + return JsonConvert.SerializeObject(me, format ? Formatting.Indented : Formatting.None); + } +} diff --git a/src/NSExt/StringExtensions.cs b/src/NSExt/StringExtensions.cs new file mode 100644 index 0000000..c025f54 --- /dev/null +++ b/src/NSExt/StringExtensions.cs @@ -0,0 +1,390 @@ +// @program: NSExt +// @file: StringExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using System.Web; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using SshNet.Security.Cryptography; +using HMACMD5 = System.Security.Cryptography.HMACMD5; + +// ReSharper disable UnusedMember.Global + +namespace NSExt; + +public static class StringExtensions +{ + /// + /// base64编码 + /// + /// 待base64编码的字符串 + /// 字符串的编码方式 + /// 编码后的base64字符串 + public static string Base64(this string me, Encoding e) + { + return e.GetBytes(me).Base64(); + } + + /// + /// base64解码 + /// + /// 待解码的字符串 + /// 解码后的原始字节数组 + public static byte[] Base64De(this string me) + { + return Convert.FromBase64String(me); + } + + /// + /// base64解码 + /// + /// 待解码的字符串 + /// 字符串的编码方式 + /// 解码后的原始字符串 + public static string Base64De(this string me, Encoding e) + { + return e.GetString(Base64De(me)); + } + + /// + /// 将易于web传输的base64web字符串转换为原生base64 + /// + /// + /// 原生base64 + public static string Base64Sys(this string me) + { + return me.Replace("-", "+").Replace("_", "/").Replace(".", "="); + } + + /// + /// 将原生base64字符串转换成易于web传输的字符串 + /// + /// + /// 易于web传输的字符串 + public static string Base64Web(this string me) + { + return me.Replace("+", "-").Replace("/", "_").Replace("=", "."); + } + + /// + /// 将字符串转换成日期对象 + /// + /// 待转换字符串 + /// 转换后的日期对象 + public static DateTime DateTime(this string me) + { + return System.DateTime.Parse(me, CultureInfo.CurrentCulture); + } + + /// + /// 将字符串转换成日期对象 + /// + /// 待转换字符串 + /// 转换失败时返回的日期对象 + /// 转换后的日期对象 + public static DateTime DateTimeTry(this string me, DateTime def) + { + return !System.DateTime.TryParse(me, out var ret) ? def : ret; + } + + /// + /// string to decimal + /// + /// string + /// decimal + public static decimal Dec(this string me) + { + return decimal.Parse(me, CultureInfo.CurrentCulture); + } + + + /// + /// 尝试将字符串转为decimal + /// + /// 字符串 + /// 转换失败后返回的默认值 + /// 转换后的decimal + public static decimal DecTry(this string me, decimal def) + { + return !decimal.TryParse(me, out var ret) ? def : ret; + } + + /// + /// 将字符串转换成枚举对象 + /// + /// + /// + /// + public static T Enum(this string name) where T : Enum + { + return (T)System.Enum.Parse(typeof(T), name); + } + + + /// + /// 将字符串转换成枚举对象 + /// + /// + /// + /// + /// + 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; + } + + + /// + /// 将字符串转为guid + /// + /// 字符串 + /// + public static Guid Guid(this string me) + { + return System.Guid.Parse(me); + } + + /// + /// 将字符串转换成guid + /// + /// 字符串 + /// 转换失败的返回值 + /// + public static Guid Guid(this string me, Guid def) + { + return System.Guid.TryParse(me, out var ret) ? ret : def; + } + + + /// + /// 将字符串转换成字节数组形式 + /// + /// 字符串 + /// 字符串使用的编码 + /// 字节数组 + public static byte[] Hex(this string me, Encoding e) + { + return e.GetBytes(me); + } + + /// + /// 解码html编码 + /// + /// html编码后的字符串 + /// 解码后的原始字符串 + public static string HtmlDe(this string me) + { + return HttpUtility.HtmlDecode(me); + } + + /// + /// string to Int32 + /// + /// string + /// Int32 + public static int Int32(this string me) + { + return int.Parse(me, CultureInfo.CurrentCulture); + } + + + /// + /// 尝试将字符串转为int32 + /// + /// 字符串 + /// 转换失败后返回的默认值 + /// 转换后的int32 + public static int Int32Try(this string me, int def) + { + return !int.TryParse(me, out var ret) ? def : ret; + } + + + /// + /// string to Int64 + /// + /// string + /// Int64 + public static long Int64(this string me) + { + return long.Parse(me, CultureInfo.CurrentCulture); + } + + /// + /// 尝试将字符串转为int64 + /// + /// 字符串 + /// 转换失败后返回的默认值 + /// 转换后的int64 + public static long Int64Try(this string me, long def) + { + return !long.TryParse(me, out var ret) ? def : ret; + } + + + /// + /// 将一个json字符串反序列化成为jObject对象 + /// + /// 字符串 + /// + public static JObject JObject(this string me) + { + return Newtonsoft.Json.Linq.JObject.Parse(me); + } + + public static string MaskChineseName(this string me) + { + if (me.Length == 2) return "*" + me[1..]; + + return me[..1] + "*" + me[^1..]; + } + + /// + /// 对一个手机号进行掩码处理 + /// + /// 手机号 + /// 掩码后的手机号 + public static string MaskMobile(this string me) + { + return new Regex(@"^(\d{3})\d{4}(\d{4})$").Replace(me, "$1****$2"); + } + + + /// + /// 对一个字符串进行md5hash运算 + /// + /// 字符串 + /// 字符串使用的编码 + /// hash摘要的16进制文本形式(无连字符小写) + public static string Md5(this string me, Encoding e) + { + using var md5 = new MD5(); + return BitConverter.ToString(md5.ComputeHash(e.GetBytes(me))) + .Replace("-", string.Empty) + .ToLower(CultureInfo.CurrentCulture); + } + + + /// + /// MD5 hmac编码 + /// + /// 字符串 + /// 密钥 + /// 字符串使用的编码 + /// hash摘要的16进制文本形式(无连字符小写) + 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); + } + + /// + /// 判断字符串是否为null或不存在子元素(如果为集合对象);如果为空,返回指定的默认值,否则返回字符串本身 + /// + /// 指定字符串 + /// 指定的默认值 + /// 如果为空,返回指定的默认值,否则返回字符串本身 + public static string NullOrEmpty(this string me, string defVal) + { + return me.AsEnumerable().NullOrEmpty() ? defVal : me; + } + + /// + /// 反序列化一个文件获得指定类型的数据对象 + /// + /// 等待反序列化的json文本 + /// 反序列化后生成的对象 + public static T Object(this string me) + { + return JsonConvert.DeserializeObject(me); + } + + /// + /// 生成密码 + /// + /// 密码原文 + /// 密文 + public static string Pwd(this string me) + { + return me.Md5Hmac(me.Md5(Encoding.UTF8), Encoding.UTF8); + } + + /// + /// 移除字符串中的html标签 + /// + /// 字符串 + /// 处理之后的字符串 + public static string RemoveHtmlTag(this string me) + { + return new Regex(@"<[^>]*>").Replace(me, ""); + } + + /// + /// 删除换行符 + /// + /// + /// + public static string RemoveWrapped(this string me) + { + return me.Replace("\r", "").Replace("\n", ""); + } + + + /// + /// 截取指定长度的字符串,代替substring + /// + /// + /// + /// + /// + public static string Sub(this string me, int startIndex, int length) + { + if (startIndex + length > me.Length) length = me.Length - startIndex; + return me.Substring(startIndex, length); + } + + /// + /// 将连续多个空格替换成一个空格 + /// + /// + /// + public static string TrimSpaces(this string me) + { + var ret = me.Replace(" ", " "); + // ReSharper disable once TailRecursiveCall + return ret == me ? ret : TrimSpaces(ret); + } + + + /// + /// url编码 + /// + /// 字符串 + /// url编码后的字符串 + public static string Url(this string me) + { + return Uri.EscapeDataString(me); + } + + /// + /// 解码url编码 + /// + /// url编码后的字符串 + /// 解码后的原始字符串 + public static string UrlDe(this string me) + { + return Uri.UnescapeDataString(me); + } + + public static int IpV4ToInt32(this string me) + { + return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0); + } +} diff --git a/src/NSExt/UriExtensions.cs b/src/NSExt/UriExtensions.cs new file mode 100644 index 0000000..ccae3eb --- /dev/null +++ b/src/NSExt/UriExtensions.cs @@ -0,0 +1,20 @@ +// @program: NSExt +// @file: UriExtensions.cs +// @author: tao ke +// @mailto: taokeu@gmail.com +// @created: 07/15/2022 16:49 + +namespace NSExt; + +public static class UriExtensions +{ + /// + /// 移除url的Scheme + /// + /// + /// + public static string RemoveScheme(this Uri me) + { + return "//" + me.Authority + me.PathAndQuery; + } +} diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/README.md @@ -0,0 +1 @@ +