7 Commits

Author SHA1 Message Date
371d0d11a5 <feat> 从资源文件读取Description 2023-01-08 19:58:16 +08:00
13f8ae51c2 Merge branch 'dev' of https://github.com/nsnail/ns-ext into dev 2023-01-04 18:21:12 +08:00
52b3170e10 bugfix 2023-01-04 18:12:44 +08:00
f3d0f98970 <fix> 2022-12-27 16:14:38 +08:00
485e7a0ead <revert> 2022-12-16 23:20:37 +08:00
943d151048 Merge branch 'dev' of https://github.com/nsnail/ns-ext into dev 2022-12-16 23:18:57 +08:00
09352ac5ea <feat> + Unicode,UnicodeDe 2022-12-16 23:11:06 +08:00
9 changed files with 121 additions and 78 deletions

View File

@ -1,27 +1,27 @@
# 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 |
| 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 |
| 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

View File

@ -0,0 +1,24 @@
namespace NSExt.Attributes;
/// <summary>
/// 指定本地化资源类型
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)]
public 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; }
}

19
src/Constant/Regexes.cs Normal file
View File

@ -0,0 +1,19 @@
namespace NSExt.Constant;
#pragma warning disable SYSLIB1045
// 使用 RegexGenerator 新特性会生成重复key值的xmlcomment导致出错
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

@ -42,17 +42,20 @@ public static class ByteExtensions
/// <param name="me">me</param>
/// <param name="upperCase">是否大写</param>
/// <param name="splitShar">字节间分隔符</param>
public static string String(this byte[] me, bool upperCase = true, string splitShar = null)
/// <param name="splitInterval">分隔符跳跃字节数</param>
public static string String(this IEnumerable<byte> me, bool upperCase = true, string splitShar = ""
, int splitInterval = 1)
{
var ret = BitConverter.ToString(me);
if (!upperCase) {
ret = ret.ToLower(CultureInfo.InvariantCulture);
var sb = new StringBuilder();
var i = 0;
foreach (var c in me.Select(x => x.ToString(upperCase ? "X2" : "x2", CultureInfo.InvariantCulture))) {
if (i++ % splitInterval == 0) {
sb.Append(splitShar);
}
sb.Append(c);
}
if (splitShar != "-") {
ret = ret.Replace("-", splitShar ?? string.Empty);
}
return ret;
return sb.ToString();
}
}

View File

@ -1,7 +1,7 @@
namespace NSExt.Extensions;
/// <summary>
/// DbCommandExtensions
/// DbCommandExtensions
/// </summary>
public static class DbCommandExtensions
{
@ -15,30 +15,18 @@ public static class DbCommandExtensions
//应逆向替换,否则由于 多个表的过滤器问题导致替换不完整 如 @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
, 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())
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")
, _ => sql.Replace(me.Parameters[i].ParameterName, me.Parameters[i].Value?.ToString())
};
}

View File

@ -1,3 +1,6 @@
using System.Reflection;
using NSExt.Attributes;
namespace NSExt.Extensions;
/// <summary>
@ -12,9 +15,15 @@ public static class EnumExtensions
/// <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)) ?? string.Empty;
var t = e.GetType();
var fi = t.GetField(Enum.GetName(t, e)!);
var descAttr = fi!.GetCustomAttribute<DescriptionAttribute>(false);
if (descAttr is null) {
return Enum.GetName(t, e);
}
var str = descAttr.Description;
var locAttr = fi!.GetCustomAttribute<LocalizationAttribute>(false);
return locAttr is null ? str : locAttr.ResourceClass.GetProperty(str)?.GetValue(default) as string ?? str;
}
}

View File

@ -15,14 +15,12 @@ public static class JsonSerializerOptionsExtensions
public static JsonSerializerOptions NewJsonSerializerOptions(this JsonSerializerOptions _)
{
return new JsonSerializerOptions {
ReadCommentHandling = JsonCommentHandling.Skip
, AllowTrailingCommas = true
, DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
, PropertyNamingPolicy = JsonNamingPolicy.CamelCase
, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
, NumberHandling
= JsonNumberHandling.AllowReadingFromString |
JsonNumberHandling.WriteAsString
ReadCommentHandling = JsonCommentHandling.Skip
, AllowTrailingCommas = true
, DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
, PropertyNamingPolicy = JsonNamingPolicy.CamelCase
, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
, NumberHandling = JsonNumberHandling.AllowReadingFromString
, PropertyNameCaseInsensitive = true
};
}

View File

@ -4,13 +4,14 @@
#pragma warning disable CA1720
using System.Security.Cryptography;
using System.Text.Json;
using NSExt.Constant;
namespace NSExt.Extensions;
/// <summary>
/// StringExtensions
/// </summary>
public static partial class StringExtensions
public static class StringExtensions
{
private static readonly JsonSerializerOptions _defaultJsonSerializerOptions
= default(JsonSerializerOptions).NewJsonSerializerOptions();
@ -369,7 +370,7 @@ public static partial class StringExtensions
/// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me)
{
return MyRegex().Replace(me, "$1****$2");
return Regexes.RegexMobile.Replace(me, "$1****$2");
}
/// <summary>
@ -444,7 +445,7 @@ public static partial class StringExtensions
/// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me)
{
return MyRegex1().Replace(me, string.Empty);
return Regexes.RegexHtmlTag.Replace(me, string.Empty);
}
/// <summary>
@ -473,7 +474,7 @@ public static partial class StringExtensions
/// </summary>
public static string Snakecase(this string me)
{
return MyRegex2().Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
return Regexes.RegexUpLetter.Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
}
/// <summary>
@ -507,6 +508,16 @@ public static partial class StringExtensions
return ret == me ? ret : ret.TrimSpaces();
}
/// <summary>
/// 将\ux0000 、 %u0000 、 &amp;#x0000; 编码转换成可读字符串
/// </summary>
public static string UnicodeDe(this string me)
{
const string replacement = "&#x$1;";
return me.Contains(@"\u") ? Regexes.RegexBacksLantUnicode.Replace(me, replacement).HtmlDe() :
me.Contains(@"%u") ? Regexes.RegexPercentUnicode.Replace(me, replacement).HtmlDe() : me.HtmlDe();
}
/// <summary>
/// url编码
/// </summary>
@ -541,13 +552,4 @@ public static partial class StringExtensions
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
[GeneratedRegex("^(\\d{3})\\d{4}(\\d{4})$")]
private static partial Regex MyRegex();
[GeneratedRegex("<[^>]*>")]
private static partial Regex MyRegex1();
[GeneratedRegex("([A-Z])")]
private static partial Regex MyRegex2();
}

View File

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