<refactor>

This commit is contained in:
2022-12-15 14:12:34 +08:00
parent 9ae1046dca
commit 3095dc783e
33 changed files with 644 additions and 259 deletions

View File

@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
/// <summary>
/// ByteExtensions
/// </summary>
public static class ByteExtensions
{
/// <summary>
@@ -12,7 +15,6 @@ public static class ByteExtensions
return Convert.ToBase64String(me);
}
/// <summary>
/// 将字节数组解码成字符串
/// </summary>
@@ -24,7 +26,6 @@ public static class ByteExtensions
return e.GetString(me);
}
/// <summary>
/// 将字节数组解码成字符串
/// </summary>
@@ -38,15 +39,20 @@ public static class ByteExtensions
/// <summary>
/// 将字节数组转换成16进制字符串
/// </summary>
/// <param name="me"></param>
/// <param name="me">me</param>
/// <param name="upperCase">是否大写</param>
/// <param name="splitShar">字节间分隔符</param>
/// <returns></returns>
public static string String(this byte[] me, bool upperCase = true, string splitShar = null)
{
var ret = BitConverter.ToString(me);
if (!upperCase) ret = ret.ToLower();
if (splitShar != "-") ret = ret.Replace("-", splitShar ?? string.Empty);
var ret = BitConverter.ToString(me);
if (!upperCase) {
ret = ret.ToLower(CultureInfo.InvariantCulture);
}
if (splitShar != "-") {
ret = ret.Replace("-", splitShar ?? string.Empty);
}
return ret;
}
}

View File

@@ -1,12 +1,13 @@
namespace NSExt.Extensions;
/// <summary>
/// CharExtensions
/// </summary>
public static class CharExtensions
{
/// <summary>
/// 是否数字或大小写字母
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
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
/// <summary>
/// 是否base64字符
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static bool IsBase64Character(this char me)
{
return IsAsciiLetterOrDigit(me) || me is '+' or '/' or '=';

View File

@@ -1,27 +1,28 @@
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
#pragma warning disable SA1300
#pragma warning disable IDE1006
namespace NSExt.Extensions;
/// <summary>
/// DateTimeExtensions
/// </summary>
public static class DateTimeExtensions
{
/// <summary>
/// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串如2秒以前3天以前
/// 将一个过去时间对象与当前时间相减转换成“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 + "秒前";
return ts.Days > 0 ? ts.Days + "天前" :
ts.Hours > 0 ? ts.Hours + "小时前" :
ts.Minutes > 0 ? ts.Minutes + "分钟前" : ts.Seconds + "前";
}
/// <summary>
/// 指定时间的世界协调时的unix时间戳形式
/// </summary>
@@ -35,55 +36,64 @@ public static class DateTimeExtensions
/// <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
/// <summary>
/// yyyy_MM
/// </summary>
public static string yyyy_MM(this DateTime me)
{
return me.ToString("yyyy-MM");
return me.ToString("yyyy-MM", CultureInfo.InvariantCulture);
}
// ReSharper disable once InconsistentNaming
/// <summary>
/// yyyy_MM_dd
/// </summary>
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
/// <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");
return me.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
}
// ReSharper disable once InconsistentNaming
/// <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");
return me.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
}
// ReSharper disable once InconsistentNaming
/// <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");
return me.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
}
// ReSharper disable once InconsistentNaming
/// <summary>
/// yyyyMM
/// </summary>
public static string yyyyMM(this DateTime me)
{
return me.ToString("yyyyMM");
return me.ToString("yyyyMM", CultureInfo.InvariantCulture);
}
// ReSharper disable once InconsistentNaming
/// <summary>
/// yyyyMMdd
/// </summary>
public static string yyyyMMdd(this DateTime me)
{
return me.ToString("yyyyMMdd");
return me.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
}
}

View File

@@ -1,28 +1,46 @@
namespace NSExt.Extensions;
/// <summary>
/// DbCommandExtensions
/// </summary>
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--)
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;
}

View File

@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
/// <summary>
/// DecimalExtensions
/// </summary>
public static class DecimalExtensions
{
/// <summary>

View File

@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
/// <summary>
/// EnumExtensions
/// </summary>
public static class EnumExtensions
{
/// <summary>
@@ -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;
}
}

View File

@@ -1,13 +1,13 @@
namespace NSExt.Extensions;
/// <summary>
/// EnumerableExtensions
/// </summary>
public static class EnumerableExtensions
{
/// <summary>
/// 将列表转成分隔符分隔的字符串
/// </summary>
/// <param name="me"></param>
/// <param name="separator"></param>
/// <returns></returns>
public static string Join(this IEnumerable<object> me, string separator)
{
return string.Join(separator, me);

View File

@@ -1,5 +1,8 @@
namespace NSExt.Extensions;
/// <summary>
/// GenericExtensions
/// </summary>
public static class GenericExtensions
{
/// <summary>
@@ -14,27 +17,24 @@ public static class GenericExtensions
, 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 (!p.CanWrite) {
continue;
}
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>
/// <typeparam name="T"></typeparam>
/// <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
public static T Is<T>(this T me, T compare, T ret)
where T : struct
{
return me.Equals(compare) ? ret : me;
}

View File

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

View File

@@ -4,9 +4,15 @@ using System.Text.Json.Serialization;
namespace NSExt.Extensions;
/// <summary>
/// JsonSerializerOptionsExtensions
/// </summary>
public static class JsonSerializerOptionsExtensions
{
public static JsonSerializerOptions NewJsonSerializerOptions(this JsonSerializerOptions me)
/// <summary>
/// NewJsonSerializerOptions
/// </summary>
public static JsonSerializerOptions NewJsonSerializerOptions(this JsonSerializerOptions _)
{
return new JsonSerializerOptions {
ReadCommentHandling = JsonCommentHandling.Skip

View File

@@ -2,48 +2,87 @@
namespace NSExt.Extensions;
/// <summary>
/// LoggerExtensions
/// </summary>
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}>";
}
private const string _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER
= "{Message} <s:{ThreadId}#{CallerName}@{CallerFilePath}:{CallerLineNumber}>";
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logDebug
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Debug, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logError
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Error, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logFatal
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Critical, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logInfo
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Information, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
private static readonly Action<ILogger, string, string, string, string, string, Exception> _logWarn
= LoggerMessage.Define<string, string, string, string, string>(LogLevel.Warning, default
, _MESSAGE_S_THREADID_CALLERNAME_CALLERFILEPATH_CALLERLINENUMBER);
/// <summary>
/// Debug
/// </summary>
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));
_logDebug(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, 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)
{
me.LogError(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
_logError(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, 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)
{
if (ex is null)
me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
else
me.LogCritical(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber), ex);
_logFatal(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, 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)
{
me.LogInformation(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
_logInfo(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, 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)
{
me.LogWarning(CallerInfoMessage(message, callerName, callerFilePath, callerLineNumber));
_logWarn(me, message.ToString(), Environment.CurrentManagedThreadId.ToString(CultureInfo.InvariantCulture)
, callerName, Path.GetFileName(callerFilePath), callerLineNumber.ToString(CultureInfo.InvariantCulture)
, null);
}
}

View File

@@ -1,15 +1,15 @@
namespace NSExt.Extensions;
/// <summary>
/// LongExtensions
/// </summary>
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
public static bool HasFlag<T>(this long me, T flag)
where T : Enum
{
var val = (long)(object)flag;
return (me & val) == val;
@@ -18,8 +18,6 @@ public static class LongExtensions
/// <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

@@ -2,6 +2,9 @@ using System.Text.Json;
namespace NSExt.Extensions;
/// <summary>
/// ObjectExtensions
/// </summary>
public static class ObjectExtensions
{
/// <summary>

View File

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

View File

@@ -1,41 +1,26 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
#pragma warning disable CA1720
using System.Security.Cryptography;
using System.Text.Json;
namespace NSExt.Extensions;
public static class StringExtensions
/// <summary>
/// StringExtensions
/// </summary>
public static partial 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>
/// aes加密
/// </summary>
/// <param name="me">要加密的串</param>
/// <param name="key">密钥</param>
/// <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)
public static string Aes(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
@@ -47,17 +32,12 @@ public static class StringExtensions
return decrypted.Base64();
}
/// <summary>
/// aes解密
/// </summary>
/// <param name="me">要加密的串</param>
/// <param name="key">密钥</param>
/// <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)
public static string AesDe(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
@@ -98,13 +78,12 @@ public static class StringExtensions
/// <returns>解码后的原始字符串</returns>
public static string Base64De(this string me, Encoding e)
{
return e.GetString(Base64De(me));
return e.GetString(me.Base64De());
}
/// <summary>
/// 将易于web传输的base64web字符串转换为原生base64
/// </summary>
/// <param name="me"></param>
/// <returns>原生base64</returns>
public static string Base64Sys(this string me)
{
@@ -114,7 +93,6 @@ public static class StringExtensions
/// <summary>
/// 将原生base64字符串转换成易于web传输的字符串
/// </summary>
/// <param name="me"></param>
/// <returns>易于web传输的字符串</returns>
public static string Base64Web(this string me)
{
@@ -156,7 +134,6 @@ public static class StringExtensions
: ret;
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
@@ -178,7 +155,6 @@ public static class StringExtensions
return decimal.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为decimal
/// </summary>
@@ -190,7 +166,6 @@ public static class StringExtensions
return !decimal.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to double
/// </summary>
@@ -204,23 +179,17 @@ public static class StringExtensions
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <returns></returns>
public static T Enum<T>(this string name) where T : Enum
public static T Enum<T>(this string name)
where T : Enum
{
return (T)System.Enum.Parse(typeof(T), name, true);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <param name="def"></param>
/// <returns></returns>
public static T EnumTry<T>(this string name, T def) where T : Enum
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;
}
@@ -235,12 +204,10 @@ public static class StringExtensions
return float.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转为guid
/// </summary>
/// <param name="me">字符串</param>
/// <returns></returns>
public static Guid Guid(this string me)
{
return System.Guid.Parse(me);
@@ -251,13 +218,11 @@ public static class StringExtensions
/// </summary>
/// <param name="me">字符串</param>
/// <param name="def">转换失败的返回值</param>
/// <returns></returns>
public static Guid Guid(this string me, Guid def)
{
return System.Guid.TryParse(me, out var ret) ? ret : def;
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
@@ -279,11 +244,10 @@ public static class StringExtensions
return me.Hex(Encoding.UTF8);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">对一个字符串进行sha1 hash运算</param>
/// <param name="me">me</param>
/// <param name="secret">密钥</param>
/// <param name="e">使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
@@ -299,8 +263,6 @@ public static class StringExtensions
/// <summary>
/// html编码
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string Html(this string me)
{
return HttpUtility.HtmlEncode(me);
@@ -337,7 +299,6 @@ public static class StringExtensions
return !int.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to Int64
/// </summary>
@@ -362,43 +323,43 @@ public static class StringExtensions
/// <summary>
/// ipv4格式转int32格式
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static int IpV4ToInt32(this string me)
{
return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0);
}
/// <summary>
/// 是否base64字符串
/// </summary>
/// <param name="me">字符串</param>
/// <returns></returns>
public static bool IsBase64String(this string me)
{
// 一个合法的Base64有着以下特征
// 字符串的长度为4的整数倍。
// 字符串的符号取值只能在A -Z, a -z, 0 -9, +, /, =共计65个字符中且 = 如果出现就必须在结尾出现。
if (!me.All(x => x.IsBase64Character())) return false;
if (me.Length % 4 != 0) return false;
if (!me.All(x => x.IsBase64Character())) {
return false;
}
if (me.Length % 4 != 0) {
return false;
}
var firstEqualSignPos = me.IndexOf('=');
if (firstEqualSignPos < 0) return true;
if (firstEqualSignPos < 0) {
return true;
}
var lastEqualSignPos = me.LastIndexOf('=');
return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '=');
}
/// <summary>
/// 中文姓名打马赛克
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
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..];
}
/// <summary>
@@ -408,10 +369,9 @@ public static class StringExtensions
/// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me)
{
return new Regex(@"^(\d{3})\d{4}(\d{4})$").Replace(me, "$1****$2");
return MyRegex().Replace(me, "$1****$2");
}
/// <summary>
/// 对一个字符串进行md5hash运算
/// </summary>
@@ -420,8 +380,7 @@ public static class StringExtensions
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
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);
}
@@ -437,12 +396,9 @@ public static class StringExtensions
return me.AsEnumerable().NullOrEmpty() ? defVal : me;
}
/// <summary>
/// null或空白字符
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static bool NullOrWhiteSpace(this string me)
{
return string.IsNullOrWhiteSpace(me);
@@ -459,7 +415,6 @@ public static class StringExtensions
return JsonSerializer.Deserialize<T>(me, options ?? _defaultJsonSerializerOptions);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
@@ -472,7 +427,6 @@ public static class StringExtensions
return JsonSerializer.Deserialize(me, type, options ?? _defaultJsonSerializerOptions);
}
/// <summary>
/// 生成密码
/// </summary>
@@ -490,20 +444,17 @@ public static class StringExtensions
/// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me)
{
return new Regex(@"<[^>]*>").Replace(me, "");
return MyRegex1().Replace(me, string.Empty);
}
/// <summary>
/// 删除换行符
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string RemoveWrapped(this string me)
{
return me.Replace("\r", "").Replace("\n", "");
return me.Replace("\r", string.Empty).Replace("\n", string.Empty);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
@@ -512,42 +463,34 @@ public static class StringExtensions
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
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);
}
/// <summary>
/// 蛇形命名
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string Snakecase(this string me)
{
return Regex.Replace(me, "([A-Z])", "-$1").ToLower().TrimStart('-');
return MyRegex2().Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
}
/// <summary>
/// 截取指定长度的字符串代替substring
/// </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)
{
if (startIndex + length > me.Length) length = me.Length - startIndex;
if (startIndex + length > me.Length) {
length = me.Length - startIndex;
}
return me.Substring(startIndex, length);
}
/// <summary>
/// 纯文本字符串转html
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string Text2Html(this string me)
{
return $"<pre>{me}</pre>";
@@ -556,15 +499,13 @@ public static class StringExtensions
/// <summary>
/// 将连续多个空格替换成一个空格
/// </summary>
/// <param name="me"></param>
/// <returns></returns>
public static string TrimSpaces(this string me)
{
var ret = me.Replace(" ", " ");
// ReSharper disable once TailRecursiveCall
return ret == me ? ret : TrimSpaces(ret);
}
// ReSharper disable once TailRecursiveCall
return ret == me ? ret : ret.TrimSpaces();
}
/// <summary>
/// url编码
@@ -585,4 +526,28 @@ public static class StringExtensions
{
return Uri.UnescapeDataString(me);
}
/// <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);
}
[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,13 +1,13 @@
namespace NSExt.Extensions;
/// <summary>
/// TypeExtensions
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。
/// </summary>
/// <param name="me"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> GetCustomAttributesIncludingBaseInterfaces<T>(this Type me)
{
var attributeType = typeof(T);

View File

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

View File

@@ -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;
global using Microsoft.Extensions.Logging;

View File

@@ -1,16 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net7.0</TargetFrameworks>
<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>
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<Import Project="../CodeQuality.props"/>
</Project>