XFEExtension
【DLL】XFE各类拓展是一个C#的DLL库,旨在优化C#代码中常用语句的使用,并提供更简洁的访问方式,同时提供Xunit测试框架,快速搭建服务器/客户端,免费ChatGPTAPI接口,免费通讯服务器,XFE下载器,新增格式等
关注
0
Fork
0
Star
0
using System.Collections;
using System.Reflection;
using XFEExtension.NetCore.XFETransform.ObjectInfoAnalyzer;
using XFEExtension.NetCore.XFETransform.StringConverter;
namespace XFEExtension.NetCore.XFETransform;
/// <summary>
/// XFE转换器
/// </summary>
public class XFEConverter
{
/// <summary>
/// 判断是否为基础类型
/// </summary>
/// <param name="type">类型</param>
/// <returns></returns>
public static bool IsBasicType(Type type)
{
return type == typeof(string) || type == typeof(int) || type == typeof(double) || type == typeof(float) || type == typeof(decimal) || type == typeof(long) || type == typeof(short) || type == typeof(byte) || type == typeof(bool) || type == typeof(char) || type == typeof(nint) || type == typeof(uint) || type == typeof(ulong) || type == typeof(ushort) || type == typeof(sbyte) || type == typeof(DateTime) || type == typeof(TimeSpan);
}
/// <summary>
/// 将基础类的文本转换为代码类型
/// </summary>
/// <param name="originString">原文本</param>
/// <returns></returns>
public static string ConvertBasicTypeToCodeType(string originString) => originString.ToLower().Replace("int32", "int").Replace("intptr", "nint").Replace("int64", "long").Replace("int16", "short").Replace("boolean", "bool").Replace("datetime", "DateTime");
/// <summary>
/// 输出类型名称
/// </summary>
/// <param name="type">类型</param>
/// <returns></returns>
public static string OutPutTypeName(Type type)
{
if (IsBasicType(type))
return ConvertBasicTypeToCodeType(type.Name);
var genericArguments = type.GetGenericArguments();
return genericArguments.Length == 0 ? type.Name : $"{type.Name.Replace($"`{genericArguments.Length}", string.Empty)}<{string.Join(", ", genericArguments.Select(x => IsBasicType(x) ? ConvertBasicTypeToCodeType(x.Name) : OutPutTypeName(x)))}>";
}
/// <summary>
/// 添加并赋值父类列表
/// </summary>
/// <param name="originalFatherList"></param>
/// <param name="value"></param>
/// <returns></returns>
public static List<object> AddAndCopyFatherList(List<object> originalFatherList, object value)
{
var newList = new List<object>();
newList.AddRange(originalFatherList);
newList.Add(value);
return newList;
}
/// <summary>
/// 获取对象信息
/// </summary>
/// <param name="stringConverter">字符串转换器</param>
/// <param name="name">对象名称</param>
/// <param name="objectPlace">对象位置</param>
/// <param name="layer">嵌套层数</param>
/// <param name="fatherObjectList">父类列表</param>
/// <param name="type">类型</param>
/// <param name="value">值</param>
/// <param name="onlyProperty">是否只获取属性</param>
/// <param name="onlyPublic">是否只获取公共成员</param>
/// <param name="stopInThisLayer">是否在该层停止递归</param>
/// <param name="maxLayer">最大解析深度</param>
/// <param name="maxArrayCount">数组列表的最大解析数量</param>
/// <param name="currentFieldInfo">字段信息</param>
/// <param name="currentPropertyInfo">属性信息</param>
/// <returns></returns>
public static IObjectInfo GetObjectInfo(IStringConverter? stringConverter, string? name, ObjectPlace objectPlace, int layer, List<object> fatherObjectList, Type? type, object? value = null, bool onlyProperty = true, bool onlyPublic = true, bool stopInThisLayer = false, int maxLayer = -1, int maxArrayCount = -1, FieldInfo? currentFieldInfo = null, PropertyInfo? currentPropertyInfo = null)
{
try
{
if (value is null || type is null)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true);
}
if (fatherObjectList.Contains(value) && layer > 0)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, "重复递归异常");
}
if (layer > maxLayer && maxLayer != -1)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"超过最大解析深度({maxLayer})");
}
var currentFatherList = AddAndCopyFatherList(fatherObjectList, value);
var isBasicType = IsBasicType(type);
if (isBasicType)
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, value);
if (type.IsAssignableTo(typeof(Enum)))
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, ObjectPlace.Enum, layer, type, false, value);
}
if (value is Exception exception)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, exception.ToString());
}
if (type.IsAssignableTo(typeof(Array)))
{
var arrayObjects = new List<IObjectInfo>();
var currentCount = 0;
foreach (var item in (Array)value)
{
currentCount++;
try
{
arrayObjects.Add(GetObjectInfo(stringConverter, "数组成员", ObjectPlace.ArrayMember, layer + 1, currentFatherList, item.GetType(), item, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
catch
{
arrayObjects.Add(GetObjectInfo(stringConverter, "数组成员", ObjectPlace.ArrayMember, layer + 1, currentFatherList, null, null, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
if (currentCount <= maxArrayCount || maxArrayCount == -1)
continue;
arrayObjects.Add(new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"数组数量超出设定最大值({maxArrayCount})"));
break;
}
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, true, value, arrayObjects);
}
if (type.IsAssignableTo(typeof(IEnumerable)))
{
var enumerableObjects = new List<IObjectInfo>();
var currentCount = 0;
foreach (var item in (IEnumerable)value)
{
currentCount++;
try
{
enumerableObjects.Add(GetObjectInfo(stringConverter, "列表成员", ObjectPlace.ListMember, layer + 1, currentFatherList, item.GetType(), item, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
catch
{
enumerableObjects.Add(GetObjectInfo(stringConverter, "列表成员", ObjectPlace.ListMember, layer + 1, currentFatherList, null, null, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
if (currentCount <= maxArrayCount || maxArrayCount == -1)
continue;
enumerableObjects.Add(new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"列表数量超出设定最大值({maxArrayCount})"));
break;
}
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, true, value, enumerableObjects);
}
if (stopInThisLayer)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, false, value);
}
var isType = value is Type || type.FullName == "System.RuntimeType";
var subObjects = new List<IObjectInfo>();
foreach (var memberInfo in type.GetMembers((onlyPublic ? BindingFlags.Public : BindingFlags.NonPublic | BindingFlags.Public) | BindingFlags.Instance | BindingFlags.Static))
{
if (memberInfo is PropertyInfo propertyInfo)
{
try
{
subObjects.Add(GetObjectInfo(stringConverter, propertyInfo.Name, ObjectPlace.Property, layer + 1, currentFatherList, propertyInfo.PropertyType, propertyInfo.GetValue(value), onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, null, propertyInfo));
}
catch
{
subObjects.Add(GetObjectInfo(stringConverter, propertyInfo.Name, ObjectPlace.Property, layer + 1, currentFatherList, propertyInfo.PropertyType, null, onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, null, propertyInfo));
}
continue;
}
if (onlyProperty || memberInfo is not FieldInfo fieldInfo)
continue;
try
{
subObjects.Add(GetObjectInfo(stringConverter, fieldInfo.Name, ObjectPlace.Field, layer + 1, currentFatherList, fieldInfo.FieldType, fieldInfo.GetValue(value), onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, fieldInfo));
}
catch
{
subObjects.Add(GetObjectInfo(stringConverter, fieldInfo.Name, ObjectPlace.Property, layer + 1, currentFatherList, fieldInfo.FieldType, null, onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, fieldInfo));
}
}
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, false, value, subObjects);
}
catch (Exception ex)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"无法获取:{ex.Message} ");
}
}
}
using System.Collections;
using System.Reflection;
using XFEExtension.NetCore.XFETransform.ObjectInfoAnalyzer;
using XFEExtension.NetCore.XFETransform.StringConverter;
namespace XFEExtension.NetCore.XFETransform;
/// <summary>
/// XFE转换器
/// </summary>
public class XFEConverter
{
/// <summary>
/// 判断是否为基础类型
/// </summary>
/// <param name="type">类型</param>
/// <returns></returns>
public static bool IsBasicType(Type type)
{
return type == typeof(string) || type == typeof(int) || type == typeof(double) || type == typeof(float) || type == typeof(decimal) || type == typeof(long) || type == typeof(short) || type == typeof(byte) || type == typeof(bool) || type == typeof(char) || type == typeof(nint) || type == typeof(uint) || type == typeof(ulong) || type == typeof(ushort) || type == typeof(sbyte) || type == typeof(DateTime) || type == typeof(TimeSpan);
}
/// <summary>
/// 将基础类的文本转换为代码类型
/// </summary>
/// <param name="originString">原文本</param>
/// <returns></returns>
public static string ConvertBasicTypeToCodeType(string originString) => originString.ToLower().Replace("int32", "int").Replace("intptr", "nint").Replace("int64", "long").Replace("int16", "short").Replace("boolean", "bool").Replace("datetime", "DateTime");
/// <summary>
/// 输出类型名称
/// </summary>
/// <param name="type">类型</param>
/// <returns></returns>
public static string OutPutTypeName(Type type)
{
if (IsBasicType(type))
return ConvertBasicTypeToCodeType(type.Name);
var genericArguments = type.GetGenericArguments();
return genericArguments.Length == 0 ? type.Name : $"{type.Name.Replace($"`{genericArguments.Length}", string.Empty)}<{string.Join(", ", genericArguments.Select(x => IsBasicType(x) ? ConvertBasicTypeToCodeType(x.Name) : OutPutTypeName(x)))}>";
}
/// <summary>
/// 添加并赋值父类列表
/// </summary>
/// <param name="originalFatherList"></param>
/// <param name="value"></param>
/// <returns></returns>
public static List<object> AddAndCopyFatherList(List<object> originalFatherList, object value)
{
var newList = new List<object>();
newList.AddRange(originalFatherList);
newList.Add(value);
return newList;
}
/// <summary>
/// 获取对象信息
/// </summary>
/// <param name="stringConverter">字符串转换器</param>
/// <param name="name">对象名称</param>
/// <param name="objectPlace">对象位置</param>
/// <param name="layer">嵌套层数</param>
/// <param name="fatherObjectList">父类列表</param>
/// <param name="type">类型</param>
/// <param name="value">值</param>
/// <param name="onlyProperty">是否只获取属性</param>
/// <param name="onlyPublic">是否只获取公共成员</param>
/// <param name="stopInThisLayer">是否在该层停止递归</param>
/// <param name="maxLayer">最大解析深度</param>
/// <param name="maxArrayCount">数组列表的最大解析数量</param>
/// <param name="currentFieldInfo">字段信息</param>
/// <param name="currentPropertyInfo">属性信息</param>
/// <returns></returns>
public static IObjectInfo GetObjectInfo(IStringConverter? stringConverter, string? name, ObjectPlace objectPlace, int layer, List<object> fatherObjectList, Type? type, object? value = null, bool onlyProperty = true, bool onlyPublic = true, bool stopInThisLayer = false, int maxLayer = -1, int maxArrayCount = -1, FieldInfo? currentFieldInfo = null, PropertyInfo? currentPropertyInfo = null)
{
try
{
if (value is null || type is null)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true);
}
if (fatherObjectList.Contains(value) && layer > 0)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, "重复递归异常");
}
if (layer > maxLayer && maxLayer != -1)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"超过最大解析深度({maxLayer})");
}
var currentFatherList = AddAndCopyFatherList(fatherObjectList, value);
var isBasicType = IsBasicType(type);
if (isBasicType)
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, value);
if (type.IsAssignableTo(typeof(Enum)))
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, ObjectPlace.Enum, layer, type, false, value);
}
if (value is Exception exception)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, exception.ToString());
}
if (type.IsAssignableTo(typeof(Array)))
{
var arrayObjects = new List<IObjectInfo>();
var currentCount = 0;
foreach (var item in (Array)value)
{
currentCount++;
try
{
arrayObjects.Add(GetObjectInfo(stringConverter, "数组成员", ObjectPlace.ArrayMember, layer + 1, currentFatherList, item.GetType(), item, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
catch
{
arrayObjects.Add(GetObjectInfo(stringConverter, "数组成员", ObjectPlace.ArrayMember, layer + 1, currentFatherList, null, null, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
if (currentCount <= maxArrayCount || maxArrayCount == -1)
continue;
arrayObjects.Add(new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"数组数量超出设定最大值({maxArrayCount})"));
break;
}
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, true, value, arrayObjects);
}
if (type.IsAssignableTo(typeof(IEnumerable)))
{
var enumerableObjects = new List<IObjectInfo>();
var currentCount = 0;
foreach (var item in (IEnumerable)value)
{
currentCount++;
try
{
enumerableObjects.Add(GetObjectInfo(stringConverter, "列表成员", ObjectPlace.ListMember, layer + 1, currentFatherList, item.GetType(), item, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
catch
{
enumerableObjects.Add(GetObjectInfo(stringConverter, "列表成员", ObjectPlace.ListMember, layer + 1, currentFatherList, null, null, onlyProperty, onlyPublic, stopInThisLayer, maxLayer, maxArrayCount, currentFieldInfo, currentPropertyInfo));
}
if (currentCount <= maxArrayCount || maxArrayCount == -1)
continue;
enumerableObjects.Add(new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"列表数量超出设定最大值({maxArrayCount})"));
break;
}
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, true, value, enumerableObjects);
}
if (stopInThisLayer)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, false, value);
}
var isType = value is Type || type.FullName == "System.RuntimeType";
var subObjects = new List<IObjectInfo>();
foreach (var memberInfo in type.GetMembers((onlyPublic ? BindingFlags.Public : BindingFlags.NonPublic | BindingFlags.Public) | BindingFlags.Instance | BindingFlags.Static))
{
if (memberInfo is PropertyInfo propertyInfo)
{
try
{
subObjects.Add(GetObjectInfo(stringConverter, propertyInfo.Name, ObjectPlace.Property, layer + 1, currentFatherList, propertyInfo.PropertyType, propertyInfo.GetValue(value), onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, null, propertyInfo));
}
catch
{
subObjects.Add(GetObjectInfo(stringConverter, propertyInfo.Name, ObjectPlace.Property, layer + 1, currentFatherList, propertyInfo.PropertyType, null, onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, null, propertyInfo));
}
continue;
}
if (onlyProperty || memberInfo is not FieldInfo fieldInfo)
continue;
try
{
subObjects.Add(GetObjectInfo(stringConverter, fieldInfo.Name, ObjectPlace.Field, layer + 1, currentFatherList, fieldInfo.FieldType, fieldInfo.GetValue(value), onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, fieldInfo));
}
catch
{
subObjects.Add(GetObjectInfo(stringConverter, fieldInfo.Name, ObjectPlace.Property, layer + 1, currentFatherList, fieldInfo.FieldType, null, onlyProperty, onlyPublic, isType, maxLayer, maxArrayCount, fieldInfo));
}
}
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, false, false, value, subObjects);
}
catch (Exception ex)
{
return new ObjectInfoImpl(currentFieldInfo, currentPropertyInfo, stringConverter, name, objectPlace, layer, type, true, $"无法获取:{ex.Message} ");
}
}
}