实现反射拓展的静态拓展类 可以获取方法/获取、设置属性及字段

这个博客介绍了`ReflectionExtension`静态类的实现,该类用于扩展反射功能,包括值的强制转换、判断是否可作为特定类型、设置和获取对象的属性或字段值。此外,还提供了获取方法信息的相关方法。
摘要由CSDN通过智能技术生成

using Rapid.Kernel.Expressions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace Rapid.Kernel.Reflection
{
    /***************************************************************************************
   **
   ** File Name(文件名) :
   * ReflectionExtension.cs
   ** Creator(创建人): 
   * LJZ
   ** Create Time(创建时间): 
   * 2020.8.28
   ** Functional Description (功能描述) : 
   * 实现反射拓展的静态拓展类。
   ** Remark(备注): 
   **
   ** Copyright(c) Rapid k1ng.LJZ Corporation.All rights reserved.  
   * ***************************************************************************************/
    /// <summary>
    /// 实现反射拓展的静态拓展类
    /// </summary>
    [Description("实现反射拓展的静态拓展类")]
    public static partial class ReflectionExtension
    {
        internal static readonly object ms_AnsycLock = new object();
        /// <summary>
        /// 默认查找级别标记
        /// </summary>
        [Description("默认查找级别标记")]
        internal static BindingFlags ms_SearchFlagDefault =
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

        #region Cast 值强制转换
        /// <summary>
        /// 值强制转换
        /// </summary>
        /// <param name="val"></param>
        /// <param name="targetType"></param>
        /// <returns></returns>
        public static object Cast(this object val, Type targetType)
        {
            if (val?.RegardAs(targetType) == true)
            {
                return val;
            }
            var tVal = (val is IConvertible
                       && targetType.IsAssignableFrom(TypeConsts.IConvertible))
                       || TypeConsts.ValuesTypes.Contains(targetType) ?
                       Convert.ChangeType(val, targetType) : val;
            if (tVal?.RegardAs(targetType) == true)
            {
                return tVal;
            }
            if (targetType.IsEnum)
            {
                tVal = Enum.Parse(targetType, tVal?.ToString());
            }
            else if (TypeConsts.Strings.Contains(tVal?.GetType()) == true)
            {
                var members = targetType.GetMember("Parse", ms_SearchFlagDefault);
                foreach (var member in members)
                {
                    if (member is MethodInfo methodInfo
                        && default !=
                        methodInfo.GetParameters()?.FirstOrDefault(
                            x => TypeConsts.Strings.Contains(x.ParameterType))
                        && methodInfo?.IsStatic == true)
                    {
                        tVal = methodInfo.Invoke(null, new object[] { tVal });
                    }
                }
            }
            return tVal;
        }

        /// <summary>
        /// 值强制转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="val"></param>
        /// <returns></returns>
        public static object Cast<T>(this object val)
        {
            var targetType = typeof(T);
            if (val?.RegardAs(targetType) == true)
            {
                return val;
            }
            var tVal = (val is IConvertible
                       && targetType.IsAssignableFrom(TypeConsts.IConvertible))
                       || TypeConsts.ValuesTypes.Contains(targetType) ?
                       Convert.ChangeType(val, targetType) : val;
            if (tVal?.RegardAs(targetType) == true)
            {
                return tVal;
            }
            if (targetType.IsEnum)
            {
                return Enum.Parse(targetType, tVal?.ToString());
            }
            else if (TypeConsts.Strings.Contains(tVal?.GetType()) == true)
            {
                var members = targetType.GetMember("Parse", ms_SearchFlagDefault);
                foreach (var member in members)
                {
                    if (member is MethodInfo methodInfo
                        && default !=
                        methodInfo.GetParameters()?.FirstOrDefault(
                            x => TypeConsts.Strings.Contains(x.ParameterType))
                        && methodInfo?.IsStatic == true)
                    {
                        return methodInfo.Invoke(null, new object[] { tVal });
                    }
                }
                //var method = members[0];
            }
            return default(T);
        }
        #endregion

        #region RegardAs 是否可被当作某个类型
        /// <summary>
        /// 是否可被当作某个类型
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="targetType"></param>
        /// <returns></returns>
        public static bool RegardAs(this Type instanceType, Type targetType)
        {
            return default != instanceType
                    && (instanceType == targetType
                    || true == instanceType?.IsSubclassOf(targetType)
                    || true == instanceType?.IsAssignableFrom(targetType)
                    || true == targetType?.IsSubclassOf(instanceType)
                    || true == targetType?.IsAssignableFrom(instanceType));
        }

        /// <summary>
        /// 是否可被当作某个类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static bool RegardAs<T>(this Type instanceType)
        {
            return RegardAs(instanceType, typeof(T));
        }
        /// <summary>
        /// 是否可被当作某个类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static bool RegardAs<T>(this object instance)
        {
            return RegardAs(instance?.GetType(), typeof(T));
        } 
        /// <summary>
          /// 是否可被当作某个类型
          /// </summary>
          /// <typeparam name="T"></typeparam>
          /// <param name="instance"></param>
          /// <returns></returns>
        public static bool RegardAs(this object instance, Type targetType)
        {
            return RegardAs(instance?.GetType(), targetType);
        }
        #endregion

        #region SetVariable 设置指定对象的变量值
        /// <summary>
        /// 设置指定对象的变量值
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="propertyOrfieldName"></param>
        /// <returns></returns>
        public static Exception SetVariable(this object instance, string propertyOrfieldName, object val)
        {
            if (default == instance)
            {
                return new Exception("instance is null");
            }
            var memberInfo = instance.GetType().GetVariableInfo(propertyOrfieldName);
            if (memberInfo is PropertyInfo propertyInfo)
            {                
                propertyInfo.SetValue(propertyInfo.IsStatic() ? null : instance, val.Cast(propertyInfo.PropertyType));
            }
            else if (memberInfo is FieldInfo fieldInfo)
            {
                fieldInfo.SetValue(fieldInfo.IsStatic() ? null : instance, val.Cast(fieldInfo.FieldType));
            }
            else if (instance is ExpandoObject
               && instance is IDictionary<string, object> expandoObj
               && expandoObj.ContainsKey(propertyOrfieldName))
            {
                expandoObj[propertyOrfieldName] = val;
            }
            return default;
        }
        #endregion

        #region GetVariable 获取指定对象的变量值
        /// <summary>
        /// 获取指定对象的变量值
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="propertyOrfieldName"></param>
        /// <returns></returns>
        public static object GetVariable(this object instance, string propertyOrfieldName)
        {
            if (default == instance)
            {
                return default;
            }
            var memberInfo = instance.GetType().GetVariableInfo(propertyOrfieldName);
            if (memberInfo is PropertyInfo propertyInfo)
            {
                return propertyInfo.GetValue(propertyInfo.IsStatic() ? null : instance);
            }
            else if (memberInfo is FieldInfo fieldInfo)
            {
                return fieldInfo.GetValue(instance);
            }
            else if (instance is ExpandoObject 
                && instance is IDictionary<string, object> expandoObj
               && expandoObj.ContainsKey(propertyOrfieldName))
            {
                return expandoObj[propertyOrfieldName];
            }
            return default;
        }

        #endregion        

        #region GetValueInfo 从指定对象的获取变量信息
        internal static Dictionary<string, List<MemberInfo>> TypesMembersDictionary { get; } = 
            new Dictionary<string, List<MemberInfo>>();
        public static List<MemberInfo> GetMembersInfos(this Type instanceType)
        {
            lock (ms_AnsycLock)
            {
                if (default == instanceType)
                    return default;
                var keyName = instanceType?.FullName;
                if (TypesMembersDictionary?.ContainsKey(keyName) == true)
                {
                    return TypesMembersDictionary[keyName];
                }
                else
                {
                    var membersInfos = instanceType.GetMembers(ms_SearchFlagDefault)?.ToList();
                    TypesMembersDictionary.Add(keyName, membersInfos);
                    return membersInfos;
                }
            }
        }
        /// <summary>
        /// 从指定对象类型的获取变量信息
        /// </summary>
        /// <param name="instanceType"></param>
        /// <param name="propertyOrfieldName"></param>
        /// <returns></returns>
        public static List<MemberInfo> GetVariablesInfos(this Type instanceType, string propertyOrfieldName = null, bool isContain = false)
        {
            lock (ms_AnsycLock)
            {
                if (default == instanceType)
                    return default;
                var memberInfos = instanceType.GetMembersInfos();
                if (!string.IsNullOrWhiteSpace(propertyOrfieldName)
                    && isContain)
                {
                    memberInfos = memberInfos.Where(x => x?.Name?.Contains(propertyOrfieldName) == true)?.ToList();
                }
                else if (!isContain
                    && !string.IsNullOrWhiteSpace(propertyOrfieldName))
                {
                    memberInfos = memberInfos.Where(x => x?.Name == propertyOrfieldName)?.ToList();
                }
                memberInfos = memberInfos.OrderBy(x=>x.MemberType)?.ToList();
                return memberInfos;
            }
        }
        /// <summary>
        /// 从指定对象类型的获取变量信息
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="propertyOrfieldName"></param>
        /// <returns></returns>
        public static List<MemberInfo> GetVariablesInfos(this object instance, string propertyOrfieldName = null, bool isContain = false)
        {           
            return instance?.GetType()?.GetVariablesInfos(propertyOrfieldName,isContain);
        }
        /// <summary>
        /// 从指定对象类型的获取变量信息
        /// </summary>
        /// <param name="instanceType"></param>
        /// <param name="propertyOrfieldName"></param>
        /// <returns></returns>
        public static MemberInfo GetVariableInfo(this Type instanceType, string propertyOrfieldName)
        {
            if (default == instanceType
                  || string.IsNullOrWhiteSpace(propertyOrfieldName))
                return default;
            if (instanceType.GetProperty(propertyOrfieldName, ms_SearchFlagDefault) is PropertyInfo propertyInfo)
                return propertyInfo;
            if (instanceType.GetField(propertyOrfieldName, ms_SearchFlagDefault) is FieldInfo fieldInfo)
                return fieldInfo;
            return default;
        }

        /// <summary>
        /// 从指定对象的获取变量信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static MemberInfo GetVariableInfo<T>(this object obj, Expression<Func<T, object>> expression)
        {
            return typeof(T)?.GetVariableInfo(expression.GetExpression());
        }
        #endregion

        #region GetMethodInfos GetMethodInfo 获取指定名称的方法信息
        #region GetMethodInfos 获取指定名称的方法信息
        /// <summary>
        /// 获取指定名称
        /// 所有方法信息
        /// </summary>
        /// <param name="instanceType">指定类型</param>
        /// <param name="methodName"></param>
        /// <returns></returns>
        public static List<MethodInfo> GetMethodInfos(this Type instanceType, string methodName)
        {
            var methods = new List<MethodInfo>();
            if (default == instanceType
                || string.IsNullOrWhiteSpace(methodName))
                return methods;
            foreach (var info in
                instanceType?.GetMembersInfos()
                ?.Where(x => MemberTypes.Method == x.MemberType
                && x.Name == methodName))
            {
                if (info is MethodInfo methodInfo)
                {
                    methods.Add(methodInfo);
                }
            }
            return methods;
        }       
        /// <summary>
        /// 获取指定名称
        /// 所有方法信息
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="methodName"></param>
        /// <returns></returns>
        public static List<MethodInfo> GetMethodInfos(this object instance, string methodName)
        {
            return GetMethodInfos(instance?.GetType(), methodName);
        }
        #endregion
        #region  GetMethodInfo 获取指定名称的方法信息
        /// <summary>
        /// 获取方法
        /// 如果存在多个方法
        /// 则直接返回参数最少的一个
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="methodName"></param>
        /// <param name="parametersTypes"></param>
        /// <returns></returns>
        public static MethodInfo GetMethodInfo(this object instance, string methodName, Type[] parametersTypes = default)
        {
            var methodInfos = instance.GetMethodInfos(methodName)?.OrderBy(
                    x => x?.GetParameters()?.Count())?.ToList();
            if (default == methodInfos)
                return default;
            if (default == parametersTypes)
                return methodInfos.FirstOrDefault();
            else
            {
                foreach (var methodInfo in methodInfos)
                {
                    if (methodInfo.GetParameters() is ParameterInfo[] parameterInfos
                        && parameterInfos?.Length == parametersTypes.Length)
                    {
                        for (var i = 0; i < parametersTypes.Length; i++)
                        {
                            if (parametersTypes[i].RegardAs(parameterInfos[i].ParameterType))
                            {
                                if (i == parametersTypes.Length - 1)
                                    return methodInfo;
                            }
                            else
                                break;
                        }
                    }
                }
                return default;
            }
        }
        #endregion
        #endregion
    }
    
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值