refactor: ♻️ 2.0 (#3)

This commit is contained in:
2023-12-14 15:03:07 +08:00
committed by GitHub
parent 8c0dbcf1f4
commit cf2988b389
73 changed files with 1157 additions and 371 deletions

View File

@ -0,0 +1,61 @@
namespace NSExt.Extensions;
/// <summary>
/// ByteExtensions
/// </summary>
public static class ByteExtensions
{
/// <summary>
/// base64编码
/// </summary>
/// <param name="me">me</param>
/// <returns>编码后的base64字符串</returns>
public static string Base64(this byte[] me)
{
return Convert.ToBase64String(me);
}
/// <summary>
/// 将字节数组解码成字符串
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码方式</param>
/// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me, Encoding e)
{
return e.GetString(me);
}
/// <summary>
/// 将字节数组解码成字符串
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string HexDe(this byte[] me)
{
return me.HexDe(Encoding.UTF8);
}
/// <summary>
/// 将字节数组转换成16进制字符串
/// </summary>
/// <param name="me">me</param>
/// <param name="upperCase">是否大写</param>
/// <param name="splitShar">字节间分隔符</param>
/// <param name="splitInterval">分隔符跳跃字节数</param>
public static string Str(this IEnumerable<byte> 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", CultureInfo.InvariantCulture))) {
if (i++ % splitInterval == 0) {
_ = sb.Append(splitShar);
}
_ = sb.Append(c);
}
return sb.ToString();
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,26 @@
namespace NSExt.Extensions;
/// <summary>
/// DecimalExtensions
/// </summary>
public static class DecimalExtensions
{
/// <summary>
/// 四舍五入后的近似值
/// </summary>
/// <param name="me">me</param>
/// <param name="place">小数点位数</param>
/// <returns>处理后的值</returns>
public static decimal Round(this decimal me, int place)
{
return Math.Round(me, place);
}
/// <summary>
/// ToString 的 Invariant 版本
/// </summary>
public static string ToInvString(this decimal me)
{
return me.ToString(CultureInfo.InvariantCulture);
}
}

View File

@ -0,0 +1,41 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using NSExt.Attributes;
namespace NSExt.Extensions;
/// <summary>
/// EnumExtensions
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// 获取显示特性
/// </summary>
public static DisplayAttribute GetDisplay(this Enum me)
{
return me.GetAttributeOfType<DisplayAttribute>();
}
/// <summary>
/// 获取枚举的本地化资源描述
/// </summary>
public static string ResDesc<T>(this Enum e)
{
var typeOfEnum = e.GetType();
var typeOfField = typeOfEnum.GetField(Enum.GetName(typeOfEnum, e)!);
var resDescAttr = typeOfField!.GetCustomAttribute<ResourceDescriptionAttribute<T>>(true);
return resDescAttr is null
? Enum.GetName(typeOfEnum, e)
: typeof(T).GetProperty(resDescAttr.ResourceName)?.GetValue(default) as string;
}
/// <summary>
/// 通过类泛型类型获取特性
/// </summary>
private static T GetAttributeOfType<T>(this Enum me)
where T : Attribute
{
return me.GetType().GetMember(me.ToString())[0].GetCustomAttributes<T>(false).FirstOrDefault();
}
}

View File

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

View File

@ -0,0 +1,41 @@
namespace NSExt.Extensions;
/// <summary>
/// GenericExtensions
/// </summary>
public static class GenericExtensions
{
/// <summary>
/// 从指定的对象拷贝属性
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="me">me</param>
/// <param name="copyObj">拷贝来源</param>
/// <param name="propNameList">需要处理的属性名</param>
/// <param name="isIncludeOrExclude">True包含false排除</param>
public static void CopyFrom<T>(this T me, T copyObj, IList<string> propNameList = null
, bool isIncludeOrExclude = false)
{
foreach (var p in me.GetType().GetProperties()) {
if (!p.CanWrite) {
continue;
}
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>
public static T Is<T>(this T me, T compare, T ret)
where T : struct
{
return me.Equals(compare) ? ret : me;
}
}

View File

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

View File

@ -0,0 +1,86 @@
// ReSharper disable TemplateIsNotCompileTimeConstantProblem
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
namespace NSExt.Extensions;
/// <summary>
/// LoggerExtensions
/// </summary>
public static class LoggerExtensions
{
private const string _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER
= "{Message} <s:{CallerName}@{CallerFilePath}:{CallerLineNumber}>";
private static readonly Action<ILogger, string, string, string, string, Exception> _logDebug
= LoggerMessage.Define<string, string, string, string>(LogLevel.Debug, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logError
= LoggerMessage.Define<string, string, string, string>(LogLevel.Error, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logFatal
= LoggerMessage.Define<string, string, string, string>(LogLevel.Critical, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logInfo
= LoggerMessage.Define<string, string, string, string>(LogLevel.Information, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
private static readonly Action<ILogger, string, string, string, string, Exception> _logWarn
= LoggerMessage.Define<string, string, string, string>(LogLevel.Warning, default
, _MESSAGE_S_THREAD_ID_CALLER_NAME_CALLER_FILE_PATH_CALLER_LINE_NUMBER);
/// <summary>
/// Debug
/// </summary>
public static void Debug(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logDebug(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
/// <summary>
/// Error
/// </summary>
public static void Error(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logError(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
/// <summary>
/// Fatal
/// </summary>
public static void Fatal(this ILogger me, object message, Exception ex = null
, [CallerMemberName] string callerName = null, [CallerFilePath] string callerFilePath = null
, [CallerLineNumber] int callerLineNumber = 0)
{
_logFatal(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), ex);
}
/// <summary>
/// Info
/// </summary>
public static void Info(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logInfo(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
/// <summary>
/// Warn
/// </summary>
public static void Warn(this ILogger me, object message, [CallerMemberName] string callerName = null
, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
_logWarn(me, message.ToString(), callerName, Path.GetFileName(callerFilePath)
, callerLineNumber.ToString(CultureInfo.InvariantCulture), null);
}
}

View File

@ -0,0 +1,42 @@
namespace NSExt.Extensions;
/// <summary>
/// LongExtensions
/// </summary>
public static class LongExtensions
{
/// <summary>
/// 判断枚举是否包含某个位
/// </summary>
public static bool HasFlag<T>(this long me, T flag)
where T : Enum
{
var val = (long)(object)flag;
return (me & val) == val;
}
/// <summary>
/// 生成随机数
/// </summary>
/// <param name="me">me</param>
public static long Rand(this long[] me)
{
return new Random(Guid.NewGuid().GetHashCode()).NextInt64(me[0], me[1]);
}
/// <summary>
/// 1970毫秒数转换成日期对象
/// </summary>
public static DateTime Time(this long msFrom1970)
{
return DateTime.UnixEpoch.AddMilliseconds(msFrom1970).ToLocalTime();
}
/// <summary>
/// ToString 的 Invariant 版本
/// </summary>
public static string ToInvString(this long me)
{
return me.ToString(CultureInfo.InvariantCulture);
}
}

View File

@ -0,0 +1,30 @@
using System.Text.Json;
namespace NSExt.Extensions;
/// <summary>
/// ObjectExtensions
/// </summary>
public static class ObjectExtensions
{
/// <summary>
/// 将一个对象序列化成json文本
/// </summary>
/// <param name="me">me</param>
/// <returns>json文本</returns>
public static string Json(this object me)
{
return JsonSerializer.Serialize(me);
}
/// <summary>
/// 将一个对象序列化成json文本
/// </summary>
/// <param name="me">me</param>
/// <param name="options">序列化选项</param>
/// <returns>json文本</returns>
public static string Json(this object me, JsonSerializerOptions options)
{
return JsonSerializer.Serialize(me, options);
}
}

View File

@ -0,0 +1,32 @@
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)) {
return me.Position;
}
}
return -1;
}
/// <summary>
/// IsTextStream
/// </summary>
public static bool IsTextStream(this Stream me)
{
#pragma warning disable IDE0300
return me.FirstByteIndex(new byte[] { 0x00, 0xff }) < 0;
#pragma warning restore IDE0300
}
}

View File

@ -0,0 +1,594 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
#pragma warning disable CA1720
using System.Security.Cryptography;
using System.Text.Json;
using System.Web;
using NSExt.Constant;
namespace NSExt.Extensions;
/// <summary>
/// StringExtensions
/// </summary>
#pragma warning disable CodeLinesAnalyzer
public static class StringExtensions
{
/// <summary>
/// aes加密
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
public static string Aes(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
aes.Key = key.Hex();
using var encryptor = aes.CreateEncryptor();
var bytes = me.Hex();
var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.Base64();
}
/// <summary>
/// aes解密
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
public static string AesDe(this string me, string key)
{
using var aes = System.Security.Cryptography.Aes.Create();
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
aes.Key = key.Hex();
using var encryptor = aes.CreateDecryptor();
var bytes = me.Base64De();
var decrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
return decrypted.HexDe();
}
/// <summary>
/// base64编码
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param>
/// <returns>编码后的base64字符串</returns>
public static string Base64(this string me, Encoding e)
{
return e.GetBytes(me).Base64();
}
/// <summary>
/// base64解码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字节数组</returns>
public static byte[] Base64De(this string me)
{
return Convert.FromBase64String(me);
}
/// <summary>
/// base64解码
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串的编码方式</param>
/// <returns>解码后的原始字符串</returns>
public static string Base64De(this string me, Encoding e)
{
return e.GetString(me.Base64De());
}
/// <summary>
/// 将易于web传输的base64web字符串转换为原生base64
/// </summary>
/// <returns>原生base64</returns>
public static string Base64Sys(this string me)
{
return me.Replace("-", "+").Replace("_", "/").Replace(".", "=");
}
/// <summary>
/// 将原生base64字符串转换成易于web传输的字符串
/// </summary>
/// <returns>易于web传输的字符串</returns>
public static string Base64Web(this string me)
{
return me.Replace("+", "-").Replace("/", "_").Replace("=", ".");
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTime(this string me)
{
return System.DateTime.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="format">日期格式</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExact(this string me, string format)
{
return System.DateTime.ParseExact(me, format, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="format">日期格式</param>
/// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeExactTry(this string me, string format, DateTime def)
{
return !System.DateTime.TryParseExact(me, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out var ret)
? def
: ret;
}
/// <summary>
/// 将字符串转换成日期对象
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败时返回的日期对象</param>
/// <returns>转换后的日期对象</returns>
public static DateTime DateTimeTry(this string me, DateTime def)
{
return !System.DateTime.TryParse(me, CultureInfo.InvariantCulture, DateTimeStyles.None, out var ret)
? def
: ret;
}
/// <summary>
/// string to decimal
/// </summary>
/// <param name="me">me</param>
/// <returns>decimal</returns>
public static decimal Dec(this string me)
{
return decimal.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为decimal
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的decimal</returns>
public static decimal DecTry(this string me, decimal def)
{
return !decimal.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to double
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static double Double(this string me)
{
return double.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
public static T Enum<T>(this string name)
where T : Enum
{
return (T)System.Enum.Parse(typeof(T), name, true);
}
/// <summary>
/// 将字符串转换成枚举对象
/// </summary>
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;
}
/// <summary>
/// string to float
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static float Float(this string me)
{
return float.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 将字符串转为guid
/// </summary>
/// <param name="me">me</param>
public static Guid Guid(this string me)
{
return System.Guid.Parse(me);
}
/// <summary>
/// 将字符串转换成guid
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败的返回值</param>
public static Guid Guid(this string me, Guid def)
{
return System.Guid.TryParse(me, out var ret) ? ret : def;
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>字节数组</returns>
public static byte[] Hex(this string me, Encoding e)
{
return e.GetBytes(me);
}
/// <summary>
/// 将字符串转换成字节数组形式
/// </summary>
/// <param name="me">me</param>
/// <returns>字节数组</returns>
public static byte[] Hex(this string me)
{
return me.Hex(Encoding.UTF8);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="secret">密钥</param>
/// <param name="e">使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string HmacSha1(this string me, string secret, Encoding e)
{
#pragma warning disable CA5350
using var hmacSha1 = new HMACSHA1(e.GetBytes(secret));
#pragma warning restore CA5350
return BitConverter.ToString(hmacSha1.ComputeHash(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
/// <summary>
/// html编码
/// </summary>
public static string Html(this string me)
{
return HttpUtility.HtmlEncode(me);
}
/// <summary>
/// 解码html编码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string HtmlDe(this string me)
{
return HttpUtility.HtmlDecode(me);
}
/// <summary>
/// string to Int32
/// </summary>
/// <param name="me">me</param>
/// <returns>Int32</returns>
public static int Int32(this string me)
{
return int.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为int32
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int32</returns>
public static int Int32Try(this string me, int def)
{
return !int.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// string to Int64
/// </summary>
/// <param name="me">me</param>
/// <returns>Int64</returns>
public static long Int64(this string me)
{
return long.Parse(me, CultureInfo.CurrentCulture);
}
/// <summary>
/// 尝试将字符串转为int64
/// </summary>
/// <param name="me">me</param>
/// <param name="def">转换失败后返回的默认值</param>
/// <returns>转换后的int64</returns>
public static long Int64Try(this string me, long def)
{
return !long.TryParse(me, out var ret) ? def : ret;
}
/// <summary>
/// ipv4格式转int32格式
/// </summary>
public static int IpV4ToInt32(this string me)
{
return BitConverter.ToInt32(me.Split('.').Select(byte.Parse).Reverse().ToArray(), 0);
}
/// <summary>
/// 是否base64字符串
/// </summary>
/// <param name="me">me</param>
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;
}
var firstEqualSignPos = me.IndexOf('=');
if (firstEqualSignPos < 0) {
return true;
}
var lastEqualSignPos = me.LastIndexOf('=');
return lastEqualSignPos == me.Length - 1 && me[firstEqualSignPos..lastEqualSignPos].All(x => x == '=');
}
/// <summary>
/// 中文姓名打马赛克
/// </summary>
public static string MaskChineseName(this string me)
{
return me.Length == 2 ? "*" + me[1..] : me[..1] + "*" + me[^1..];
}
/// <summary>
/// 对一个手机号进行掩码处理
/// </summary>
/// <param name="me">me</param>
/// <returns>掩码后的手机号</returns>
public static string MaskMobile(this string me)
{
return Regexes.RegexMobile.Replace(me, "$1****$2");
}
/// <summary>
/// 对一个字符串进行md5hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Md5(this string me, Encoding e)
{
#pragma warning disable CA5351
return BitConverter.ToString(MD5.HashData(e.GetBytes(me)))
#pragma warning restore CA5351
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
/// <summary>
/// 判断字符串是否为null或不存在子元素如果为集合对象如果为空返回指定的默认值否则返回字符串本身
/// </summary>
/// <param name="me">me</param>
/// <param name="defVal">指定的默认值</param>
/// <returns>如果为空,返回指定的默认值,否则返回字符串本身</returns>
public static string NullOrEmpty(this string me, string defVal)
{
return me.AsEnumerable().NullOrEmpty() ? defVal : me;
}
/// <summary>
/// null或空白字符
/// </summary>
public static bool NullOrWhiteSpace(this string me)
{
return string.IsNullOrWhiteSpace(me);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
/// <param name="me">me</param>
/// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns>
public static T Object<T>(this string me, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize<T>(me, options);
}
/// <summary>
/// 反序列化一个文件获得指定类型的数据对象
/// </summary>
/// <param name="me">me</param>
/// <param name="type">实际类型</param>
/// <param name="options">序列化选项</param>
/// <returns>反序列化后生成的对象</returns>
public static object Object(this string me, Type type, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize(me, type, options);
}
/// <summary>
/// 生成密码
/// </summary>
/// <param name="me">me</param>
/// <returns>密文</returns>
public static string Pwd(this string me)
{
return me.Md5Hmac(me.Md5(Encoding.UTF8), Encoding.UTF8);
}
/// <summary>
/// 移除字符串中的html标签
/// </summary>
/// <param name="me">me</param>
/// <returns>处理之后的字符串</returns>
public static string RemoveHtmlTag(this string me)
{
return Regexes.RegexHtmlTag.Replace(me, string.Empty);
}
/// <summary>
/// 删除换行符
/// </summary>
public static string RemoveWrapped(this string me)
{
return me.Replace("\r", string.Empty).Replace("\n", string.Empty);
}
/// <summary>
/// 对一个字符串进行sha1 hash运算
/// </summary>
/// <param name="me">me</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
public static string Sha1(this string me, Encoding e)
{
#pragma warning disable CA5350
return BitConverter.ToString(SHA1.HashData(e.GetBytes(me)))
#pragma warning restore CA5350
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
/// <summary>
/// 蛇形命名
/// </summary>
public static string SnakeCase(this string me)
{
return Regexes.RegexUpLetter.Replace(me, "-$1").ToLower(CultureInfo.InvariantCulture).TrimStart('-');
}
/// <summary>
/// 截取指定长度的字符串代替substring
/// </summary>
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);
}
/// <summary>
/// 纯文本字符串转html
/// </summary>
public static string Text2Html(this string me)
{
return $"<pre>{me}</pre>";
}
/// <summary>
/// 首字母小写
/// </summary>
public static string ToLowerCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me)
? me
: string.Concat( //
me[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(), me.AsSpan(1));
}
/// <summary>
/// 首字母大写
/// </summary>
public static string ToUpperCamelCase(this string me)
{
return string.IsNullOrWhiteSpace(me) ? me : string.Concat(me[0].ToString().ToUpperInvariant(), me.AsSpan(1));
}
/// <summary>
/// 将连续多个空格替换成一个空格
/// </summary>
public static string TrimSpaces(this string me)
{
var ret = me.Replace(" ", " ");
// ReSharper disable once TailRecursiveCall
return ret == me ? ret : ret.TrimSpaces();
}
/// <summary>
/// 将\ux0000 、 %u0000 、 &amp;#x0000; 编码转换成可读字符串
/// </summary>
public static string UnicodeDe(this string me)
{
const string replacement = "&#x$1;";
if (me.Contains(@"\u")) {
return Regexes.RegexBacksLantUnicode.Replace(me, replacement).HtmlDe();
}
// ReSharper disable once ConvertIfStatementToReturnStatement
#pragma warning disable IDE0046
if (me.Contains("%u")) {
#pragma warning restore IDE0046
return Regexes.RegexPercentUnicode.Replace(me, replacement).HtmlDe();
}
return me.HtmlDe();
}
/// <summary>
/// url编码
/// </summary>
/// <param name="me">me</param>
/// <returns>url编码后的字符串</returns>
public static string Url(this string me)
{
return Uri.EscapeDataString(me);
}
/// <summary>
/// 解码url编码
/// </summary>
/// <param name="me">me</param>
/// <returns>解码后的原始字符串</returns>
public static string UrlDe(this string me)
{
return Uri.UnescapeDataString(me);
}
/// <summary>
/// MD5 hmac编码
/// </summary>
/// <param name="me">me</param>
/// <param name="key">密钥</param>
/// <param name="e">字符串使用的编码</param>
/// <returns>hash摘要的16进制文本形式无连字符小写</returns>
private static string Md5Hmac(this string me, string key, Encoding e)
{
#pragma warning disable CA5351
using var md5Hmac = new HMACMD5(e.GetBytes(key));
#pragma warning restore CA5351
return BitConverter.ToString(md5Hmac.ComputeHash(e.GetBytes(me)))
.Replace("-", string.Empty)
.ToLower(CultureInfo.CurrentCulture);
}
}
#pragma warning restore CodeLinesAnalyzer

View File

@ -0,0 +1,19 @@
namespace NSExt.Extensions;
/// <summary>
/// TypeExtensions
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// 搜索此成员的继承链以查找自定义属性,接口也会被搜索。
/// </summary>
public static IEnumerable<T> GetCustomAttributesIncludingBaseInterfaces<T>(this Type me)
{
var attributeType = typeof(T);
return me.GetCustomAttributes(attributeType, true)
.Union(me.GetInterfaces()
.SelectMany(interfaceType => interfaceType.GetCustomAttributes(attributeType, true)))
.Cast<T>();
}
}

View File

@ -0,0 +1,15 @@
namespace NSExt.Extensions;
/// <summary>
/// UriExtensions
/// </summary>
public static class UriExtensions
{
/// <summary>
/// 移除url的Scheme
/// </summary>
public static string RemoveScheme(this Uri me)
{
return "//" + me.Authority + me.PathAndQuery;
}
}