using System; using System.Collections.Generic; using System.ComponentModel; using System.Dynamic; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Xml; namespace CloudBuilder.Core.Extensions { /// /// 基类型扩展辅助操作类 /// public static class ObjectExtensions { #region 公共方法 /// /// 把对象类型转换为指定类型 /// /// /// /// public static object CastTo(this object value, Type conversionType) { if (value == null) { return null; } if (conversionType.IsNullableType()) { conversionType = conversionType.GetUnNullableType(); } if (conversionType.IsEnum) { return Enum.Parse(conversionType, value.ToString()); } if (conversionType == typeof(Guid)) { return Guid.Parse(value.ToString()); } return Convert.ChangeType(value, conversionType); } /// /// 把对象类型转化为指定类型 /// /// 动态类型 /// 要转化的源对象 /// 转化后的指定类型的对象,转化失败引发异常。 public static T CastTo(this object value) { if (value == null && default(T) == null) { return default(T); } if (value.GetType() == typeof(T)) { return (T)value; } object result = CastTo(value, typeof(T)); return (T)result; } /// /// 把对象类型转化为指定类型,转化失败时返回指定的默认值 /// /// 动态类型 /// 要转化的源对象 /// 转化失败返回的指定默认值 /// 转化后的指定类型对象,转化失败时返回指定的默认值 public static T CastTo(this object value, T defaultValue) { try { return CastTo(value); } catch (Exception) { return defaultValue; } } /// /// 判断当前值是否介于指定范围内 /// /// 动态类型 /// 动态类型对象 /// 范围起点 /// 范围终点 /// 是否可等于上限(默认等于) /// 是否可等于下限(默认等于) /// 是否介于 public static bool IsBetween(this IComparable value, T start, T end, bool leftEqual = true, bool rightEqual = true) where T : IComparable { bool flag = leftEqual ? value.CompareTo(start) >= 0 : value.CompareTo(start) > 0; return flag && (rightEqual ? value.CompareTo(end) <= 0 : value.CompareTo(end) < 0); } /// /// 判断当前值是否介于指定范围内 /// /// 动态类型 /// 动态类型对象 /// 范围小值 /// 范围大值 /// 是否可等于小值(默认等于) /// 是否可等于大值(默认等于) public static bool IsInRange(this IComparable value, T min, T max, bool minEqual = true, bool maxEqual = true) where T : IComparable { bool flag = minEqual ? value.CompareTo(min) >= 0 : value.CompareTo(min) > 0; return flag && (maxEqual ? value.CompareTo(max) <= 0 : value.CompareTo(max) < 0); } /// /// 是否存在于 /// public static bool IsIn(this T value, params T[] source) { return source.Contains(value); } /// /// 将对象[主要是匿名对象]转换为dynamic /// public static dynamic ToDynamic(this object value) { IDictionary expando = new ExpandoObject(); Type type = value.GetType(); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(type); foreach (PropertyDescriptor property in properties) { var val = property.GetValue(value); if (property.PropertyType.FullName != null && property.PropertyType.FullName.StartsWith("<>f__AnonymousType")) { dynamic dval = val.ToDynamic(); expando.Add(property.Name, dval); } else { expando.Add(property.Name, val); } } return (ExpandoObject)expando; } /// /// 将 DateTimeOffset 转换成本地 DateTime /// /// /// public static DateTime ConvertToDateTime(this DateTimeOffset dateTime) { if (dateTime.Offset.Equals(TimeSpan.Zero)) return dateTime.UtcDateTime; if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) return dateTime.ToLocalTime().DateTime; else return dateTime.DateTime; } /// /// 将 DateTimeOffset? 转换成本地 DateTime? /// /// /// public static DateTime? ConvertToDateTime(this DateTimeOffset? dateTime) { return dateTime.HasValue ? dateTime.Value.ConvertToDateTime() : null; } /// /// 将 DateTime 转换成 DateTimeOffset /// /// /// public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime) { return DateTime.SpecifyKind(dateTime, DateTimeKind.Local); } /// /// 将 DateTime? 转换成 DateTimeOffset? /// /// /// public static DateTimeOffset? ConvertToDateTimeOffset(this DateTime? dateTime) { return dateTime.HasValue ? dateTime.Value.ConvertToDateTimeOffset() : null; } /// /// 将时间戳转换为 DateTime /// /// /// internal static DateTime ConvertToDateTime(this long timestamp) { var timeStampDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var digitCount = (int)Math.Floor(Math.Log10(timestamp) + 1); if (digitCount != 13 && digitCount != 10) { throw new ArgumentException("Data is not a valid timestamp format."); } return (digitCount == 13 ? timeStampDateTime.AddMilliseconds(timestamp) // 13 位时间戳 : timeStampDateTime.AddSeconds(timestamp)).ToLocalTime(); // 10 位时间戳 } /// /// 将 IFormFile 转换成 byte[] /// /// /// //public static byte[] ToByteArray(this IFormFile formFile) //{ // var fileLength = formFile.Length; // using var stream = formFile.OpenReadStream(); // var bytes = new byte[fileLength]; // stream.Read(bytes, 0, (int)fileLength); // return bytes; //} /// /// 将流保存到本地磁盘 /// /// /// /// public static void CopyToSave(this Stream stream, string path) { // 空检查 if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path)); using var fileStream = File.Create(path); stream.CopyTo(fileStream); } /// /// 将字节数组保存到本地磁盘 /// /// /// /// public static void CopyToSave(this byte[] bytes, string path) { using var stream = new MemoryStream(bytes); stream.CopyToSave(path); } /// /// 将流保存到本地磁盘 /// /// /// /// public static async Task CopyToSaveAsync(this Stream stream, string path) { // 空检查 if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path)); using var fileStream = File.Create(path); await stream.CopyToAsync(fileStream); } /// /// 将字节数组保存到本地磁盘 /// /// /// /// public static async Task CopyToSaveAsync(this byte[] bytes, string path) { using var stream = new MemoryStream(bytes); await stream.CopyToSaveAsync(path); } /// /// 判断类型是否实现某个泛型 /// /// 类型 /// 泛型类型 /// bool public static bool HasImplementedRawGeneric(this Type type, Type generic) { // 检查接口类型 var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType); if (isTheRawGenericType) return true; // 检查类型 while (type != null && type != typeof(object)) { isTheRawGenericType = IsTheRawGenericType(type); if (isTheRawGenericType) return true; type = type.BaseType; } return false; // 判断逻辑 bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type); } #endregion } }