using System.Collections; using System.Reflection; using XFEExtension.NetCore.XFETransform.ObjectInfoAnalyzer; using XFEExtension.NetCore.XFETransform.StringConverter; namespace XFEExtension.NetCore.XFETransform; /// /// XFE转换器 /// public class XFEConverter { /// /// 判断是否为基础类型 /// /// 类型 /// 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); } /// /// 将基础类的文本转换为代码类型 /// /// 原文本 /// 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"); /// /// 输出类型名称 /// /// 类型 /// 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)))}>"; } /// /// 添加并赋值父类列表 /// /// /// /// public static List AddAndCopyFatherList(List originalFatherList, object value) { var newList = new List(); newList.AddRange(originalFatherList); newList.Add(value); return newList; } /// /// 获取对象信息 /// /// 字符串转换器 /// 对象名称 /// 对象位置 /// 嵌套层数 /// 父类列表 /// 类型 /// 值 /// 是否只获取属性 /// 是否只获取公共成员 /// 是否在该层停止递归 /// 最大解析深度 /// 数组列表的最大解析数量 /// 字段信息 /// 属性信息 /// public static IObjectInfo GetObjectInfo(IStringConverter? stringConverter, string? name, ObjectPlace objectPlace, int layer, List 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(); 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(); 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(); 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} "); } } }