zoukankan      html  css  js  c++  java
  • 浅析.NET的反射特性

         在.net框架体系内,反射特性较多的应用到。反射的相关定义分为两种。

         自然解释:射是一种自然现象,表现为受刺激物对刺激物的逆反应;这是反射的字面解释,我们看一下计算机编程中的反射;

         编程解释:通过 System.Reflection 命名空间中的类以 System.Type您可以获取有关已加载的程序集和在其中定义的类型(如接口值类型)的信息。 您也可以使用反射在运行时创建类型实例,以及调用和访问这些实。

         反射(Reflection)有下列用途:它允许在运行时查看属性(attribute)信息;它允许审查集合中的各种类型,以及实例化这些类型;它允许延迟绑定的方法和属性(property);它允许在运行时创建新类型,然后使用这些类型执行一些任务。

         下面介绍一下有关反射的程序集的相关属性和方法的源码:

            (1).Object的GetType()方法:

        // Returns a Type object which represent this object instance.
        // 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [Pure]
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        public extern Type GetType();

          (2).PropertyInfo的GetProperty()方法:

     public PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder, 
                            Type returnType, Type[] types, ParameterModifier[] modifiers)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                if (types == null)
                    throw new ArgumentNullException("types");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
            }
    
            public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                if (types == null)
                    throw new ArgumentNullException("types");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
            }
    
            public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,bindingAttr,null,null,null,null);
            }
    
            public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                if (types == null)
                    throw new ArgumentNullException("types");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
            }
    
            public PropertyInfo GetProperty(String name, Type[] types)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                if (types == null)
                    throw new ArgumentNullException("types");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
            }
    
            public PropertyInfo GetProperty(String name, Type returnType)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                if (returnType == null)
                    throw new ArgumentNullException("returnType");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
            }
    
            internal PropertyInfo GetProperty(String name, BindingFlags bindingAttr, Type returnType)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                if (returnType == null)
                    throw new ArgumentNullException("returnType");
                Contract.EndContractBlock();
                return GetPropertyImpl(name, bindingAttr, null, returnType, null, null);
            }
    
            public PropertyInfo GetProperty(String name)
            {
                if (name == null)
                    throw new ArgumentNullException("name");
                Contract.EndContractBlock();
                return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
            }

       (3).Object的GetValue()方法:

    [DebuggerStepThroughAttribute]
            [Diagnostics.DebuggerHidden]
            public Object GetValue(Object obj)
            {
                return GetValue(obj, null);
            }
    
            [DebuggerStepThroughAttribute]
            [Diagnostics.DebuggerHidden]
            public virtual Object GetValue(Object obj,Object[] index)
            {
                return GetValue(obj, BindingFlags.Default, null, index, null);
            }
    
            public abstract Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture);

      以上介绍了一下有关反射的相关方法的底层方法源码,现在介绍一下较为通用的方法:

        (1).获取对象的所有公共属性。

            /// <summary>
            /// 获取对象的所有公共属性。
            /// </summary>
            /// <param name="obj">定义该方法的数据类型。</param>
            /// <returns>返回包含该对象的属性信息的数组。</returns>
            public static IEnumerable<PropertyInfo> GetProperties(this object obj)
            {
                return obj.GetType().GetProperties();
            }

        (2).获取一个对象的属性。

            /// <summary>
            ///获取一个对象的属性。
            /// </summary>
            /// <param name="obj">定义该方法的数据类型。gb</param>
            /// <param name="flags">提供要确定要检索的属性的标志。</param>
            /// <returns>返回包含该对象的属性信息的数组。</returns>
            public static IEnumerable<PropertyInfo> GetProperties(this object obj, BindingFlags flags)
            {
                return obj.GetType().GetProperties(flags);
            }

        (3).用指定名称获取具有指定名称的属性的当前对象的属性值。

            /// <summary>
            ///用指定名称获取具有指定名称的属性的当前对象的属性值。
            /// </summary>
            /// <param name="obj">要检索的属性值的对象。</param>
            /// <param name="propertyName">要检索的属性的名称。</param>
            /// <returns>返回属性的值。</returns>
            public static object GetPropertyValue(this object obj, string propertyName)
            {
                var item = obj.GetType().GetProperty(propertyName);
    
                if (item == null) return null;
                var value = obj.GetType().GetProperty(propertyName).GetValue(obj);
    
                if (item.PropertyType.IsGenericType)
                {
                    value = item.PropertyType.GetProperty(propertyName);
                }
                return value;
            }

         (4).获取一个枚举字符串值。

            /// <summary>
            ///获取一个枚举字符串值。
            /// </summary>
            /// <param name="obj">该枚举返回的字符串值。</param>
            /// <returns>返回一个枚举字符串值。</returns>
            public static string GetStringValue(this System.Enum obj)
            {
                var fieldInfo = obj.GetType().GetField(obj.ToString());
                var attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
    
                var output = (StringValueAttribute)attributes.GetValue(0);
    
                return output.Text;
            }

         (5).获取方法调用。

            /// <summary>
            /// 获取方法调用
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="action"></param>
            /// <returns></returns>
            public static MethodCallExpression GetMethodCall<T>(Expression<T>  action )
            {
                var call = action.Body as MethodCallExpression;
    
                return call;
            }

        (6).获取类型名称.

            /// <summary>
            /// 获取类型名称
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public static string GetTypeName<T>()
            {
                return typeof (T).Name;
            }

        (7).获取参数值

            /// <summary>
            /// 获取参数值
            /// </summary>
            /// <param name="methodCall"></param>
            /// <returns></returns>
            public static IEnumerable<Tuple<ParameterInfo, object>> GetArgumentValues(MethodCallExpression methodCall)
            {
                var parameters = methodCall.Method.GetParameters();
                if (!parameters.Any()) yield break;
                for(var i = 0; i < parameters.Length; i++)
                {
                    var arg = methodCall.Arguments[i];
    
                    var ceValue = arg as ConstantExpression;
    
                    if (ceValue != null)
                        yield return new Tuple<ParameterInfo, object>(parameters[i], ceValue.Value);
                    else
                        yield return new Tuple<ParameterInfo, object>(parameters[i], GetExpressionValue(arg));
                }
            }

        (8).获取表达式值

            /// <summary>
            /// 获取表达式值
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            private static object GetExpressionValue(Expression expression)
            {
                var lambda = Expression.Lambda<Func<object>>(Expression.Convert(expression, typeof (object)));
                var func = lambda.Compile();
                return func();
            }

        反射类的继承层次如下:

          System.reflection  

          System.Reflection.Assembly 

      System.Reflection.MemberInfo
      System.Reflection.EventInfo
      System.Reflection.FieldInfo
      System.Reflection.MethodBase
      System.Reflection.ConstructorInfo
      System.Reflection.MethodInfo
      System.Reflection.PropertyInfo
      System.Type   

  • 相关阅读:
    CSS-DAY03
    Java语言支持的8种基本数据类型
    Linux目录结构
    面向对象的四个基本特征
    使用AVADA头部有搜索icon怎么去掉?
    在ubuntu 上使用apt-get安装 任意版本
    ubuntu 14.04 nginx 1.12.2 配置https遇见的坑
    java Process执行linux命令
    node.js 接收上传的文件
    node.js 进行http get 向服务端请求
  • 原文地址:https://www.cnblogs.com/pengze0902/p/5986504.html
Copyright © 2011-2022 走看看