ZhiYeJianKang_PeiXun/cyqdata-master/Tool/ReflectTool.cs
2025-02-20 15:41:53 +08:00

347 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace CYQ.Data.Tool
{
/// <summary>
/// 反射工具(带缓存)
/// </summary>
public static class ReflectTool
{
/// <summary>
/// 将PropertyInfo[] 改成PropertyInfo List是因为.NET的CLR会引发内存读写异常启用IntelliTrace时
/// </summary>
static MDictionary<string, List<PropertyInfo>> propCache = new MDictionary<string, List<PropertyInfo>>();
static MDictionary<string, List<FieldInfo>> fieldCache = new MDictionary<string, List<FieldInfo>>();
static MDictionary<string, object[]> attrCache = new MDictionary<string, object[]>();
static MDictionary<string, Type[]> argumentCache = new MDictionary<string, Type[]>();
static MDictionary<int, bool> attrExistsCache = new MDictionary<int, bool>();
/// <summary>
/// 获取属性列表
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public static List<PropertyInfo> GetPropertyList(Type t)
{
bool isAnonymousType = t.Name.Contains("f__AnonymousType");//忽略匿名类型
string key = t.FullName;// t.GUID.ToString();由泛型 XX<T> 引起的如: Ge<A> 和 Ge<B> ,Guid名相同,所以用FullName
if (!isAnonymousType && propCache.ContainsKey(key))
{
return propCache[key];
}
else
{
bool isInheritOrm = t.BaseType != null && (t.BaseType.Name.StartsWith("OrmBase") || t.BaseType.Name.StartsWith("SimpleOrmBase"));
PropertyInfo[] pInfo = isInheritOrm ? t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) : t.GetProperties();
List<PropertyInfo> list = new List<PropertyInfo>(pInfo.Length);
try
{
list.AddRange(pInfo);
if (!isAnonymousType)
{
propCache.Set(key, list);
}
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
return list;
}
}
/// <summary>
/// 获取Field列表
/// </summary>
public static List<FieldInfo> GetFieldList(Type t)
{
string key = t.GUID.ToString();
if (fieldCache.ContainsKey(key))
{
return fieldCache[key];
}
else
{
bool isInheritOrm = t.BaseType != null && (t.BaseType.Name == "OrmBase" || t.BaseType.Name == "SimpleOrmBase");
FieldInfo[] pInfo = isInheritOrm ? t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) : t.GetFields();
List<FieldInfo> list = new List<FieldInfo>(pInfo.Length);
try
{
list.AddRange(pInfo);
fieldCache.Set(key, list);
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
return list;
}
}
/// <summary>
/// 获取泛型的参数长度(非泛型按默认方法计算)
/// </summary>
public static int GetArgumentLength(ref Type t)
{
Type[] argTypes;
return GetArgumentLength(ref t, out argTypes);
}
/// <summary>
/// 获取泛型的参数长度,同时类型修改为普通类型(非泛型按默认方法计算)
/// </summary>
public static int GetArgumentLength(ref Type t, out Type[] argTypes)
{
argTypes = null;
string key = t.FullName;
if (argumentCache.ContainsKey(key))
{
argTypes = argumentCache[key];
}
else
{
int len = 0;
if (t.IsGenericType)
{
#region MyRegion
argTypes = t.GetGenericArguments();
len = argTypes.Length;
for (int i = 0; i < argTypes.Length; i++)
{
if (argTypes[i].IsGenericType && argTypes[i].Name.StartsWith("Nullable"))
{
argTypes[i] = Nullable.GetUnderlyingType(argTypes[i]);
}
}
#endregion
}
else
{
#region
if (t.Name.EndsWith("[]"))
{
len = 1;
argTypes = new Type[1] { t.GetElementType() };
}
else if (t.Name == "MDataRowCollection" || t.Name == "MDataColumn")
{
len = 1;
}
else if (t.Name == "NameValueCollection" || (t.BaseType != null && t.BaseType.Name == "NameValueCollection"))
{
len = 2;
}
else if (t.BaseType != null && t.BaseType.Name == "DbParameterCollection")
{
len = 1;
}
else
{
System.Reflection.MethodInfo[] mis = t.GetMethods();
if (mis != null)
{
foreach (System.Reflection.MethodInfo mi in mis)
{
if (mi.Name == "Add")
{
len = mi.GetParameters().Length;
break;
}
}
}
//System.Reflection.MethodInfo mi = t.GetMethod("Add");
//if (mi != null)
//{
// len = mi.GetParameters().Length;
//}
}
if (argTypes == null)
{
argTypes = new Type[len];
for (int i = 0; i < argTypes.Length; i++)
{
argTypes[i] = typeof(object);
}
}
#endregion
}
argumentCache.Set(key, argTypes);
}
if (t.IsGenericType)
{
if (t.Name.StartsWith("Nullable"))
{
t = Nullable.GetUnderlyingType(t);
}
else if (t.Name == "IList`1")
{
//List<int> a;typeof(List<int>);
t = typeof(List<>).MakeGenericType(argTypes[0]);
}
else if (t.Name == "IDictionary`2")
{
t = typeof(Dictionary<,>).MakeGenericType(argTypes[0], argTypes[1]);
}
}
return argTypes.Length;
}
public static object[] GetAttributes(FieldInfo fi, Type searchType)
{
return GetAttributes(fi.DeclaringType, searchType, null, fi);
}
public static object[] GetAttributes(PropertyInfo pi, Type searchType)
{
return GetAttributes(pi.DeclaringType, searchType, pi, null);
}
public static object[] GetAttributes(Type t, Type searchType)
{
return GetAttributes(t, searchType, null, null);
}
/// <summary>
/// 获取特性列表
/// </summary>
private static object[] GetAttributes(Type t, Type searchType, PropertyInfo pi, FieldInfo fi)
{
string key = t.GUID.ToString();
if (searchType != null)
{
key += searchType.Name;
}
if (pi != null)
{
key += pi.Name;
}
else if (fi != null)
{
key += fi.Name;
}
//key = key.GetHashCode().ToString();
if (attrCache.ContainsKey(key))
{
return attrCache[key];
}
else
{
try
{
object[] items = null;
if (pi != null)
{
items = searchType == null ? pi.GetCustomAttributes(false) : pi.GetCustomAttributes(searchType, true);
}
else if (fi != null)
{
items = searchType == null ? fi.GetCustomAttributes(false) : fi.GetCustomAttributes(searchType, true);
}
else
{
items = searchType == null ? t.GetCustomAttributes(false) : t.GetCustomAttributes(searchType, true);
}
attrCache.Add(key, items);
return items;
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
return null;
}
}
internal static T GetAttr<T>(PropertyInfo pi, FieldInfo fi)
{
Type type = typeof(T);
object[] attr = null;
if (pi != null)
{
attr = GetAttributes(pi, type);
}
else
{
attr = GetAttributes(fi, type);
}
if (attr != null && attr.Length == 1)
{
return (T)attr[0];
}
return default(T);
}
/// <summary>
/// 判断是否存在指定的属性
/// </summary>
/// <param name="searchType"></param>
/// <param name="pi"></param>
/// <returns></returns>
internal static bool ExistsAttr(Type searchType, PropertyInfo pi, FieldInfo fi)
{
string key = (pi != null ? pi.DeclaringType.FullName + pi.Name : fi.DeclaringType.FullName + fi.Name) + searchType.Name;
int code = key.GetHashCode();
if (attrExistsCache.ContainsKey(code))
{
return attrExistsCache[code];
}
object[] items = pi != null ? pi.GetCustomAttributes(searchType, true) : fi.GetCustomAttributes(searchType, true);
if (items != null && items.Length > 0)
{
attrExistsCache.Add(code, true);
return true;
}
attrExistsCache.Add(code, false);
return false;
}
/// <summary>
/// 获取系统类型若是Nullable类型则转为基础类型。
/// </summary>
public static SysType GetSystemType(ref Type t)
{
if (t.IsEnum)
{
return SysType.Enum;
}
if (t.FullName.EndsWith("[]"))
{
return SysType.Array;
}
if (t.FullName.StartsWith("System.") || t.Name.StartsWith("MDictionary") || t.Name.StartsWith("MList")) // 系统类型
{
if (t.IsGenericType)
{
if (t.Name.StartsWith("Nullable"))//int? id
{
t = Nullable.GetUnderlyingType(t);
return SysType.Base;
}
return SysType.Generic;
}
else if (t.FullName.StartsWith("System.Collections."))
{
return SysType.Collection;
}
else if (t.Name.EndsWith("[]"))
{
return SysType.Array;
}
if (t.FullName.Split('.').Length > 2)
{
return SysType.Custom;
}
return SysType.Base;
}
else
{
return SysType.Custom;
}
}
}
}