文档章节

浅析.NET的反射特性

彭泽0902
 彭泽0902
发布于 2016/11/24 18:47
字数 1184
阅读 6
收藏 0

     在.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   

 

© 著作权归作者所有

共有 人打赏支持
彭泽0902
粉丝 0
博文 44
码字总数 57771
作品 0
武汉
高级程序员
私信 提问
逃脱Asp.Net MVC框架的枷锁,使用Razor视图引擎

更多背景参看 前传:Razor视图引擎浅析 后续: eLiteWeb框架MVC(Model-View-Command) 机制解析 为什么要这么做? 1. Asp.Net MVC 其实也不是太好 2. 我有自己的敏捷Web框架, 仍然想用Razor引擎...

予沁安
2012/11/26
0
33
Instant Run 浅析

Instant Run 浅析 Jason's Blog2015-11-24314 阅读 GradleStudioAndroid AS2.0 Preview 版本发布了,早上醒来就被各种刷屏,有人在担心更新,有人在拍手称快,有人在厕所哭晕。而我当然没有那...

Jason's Blog
2015/11/24
0
0
Java 反射机制浅析(重要)

自己对java的运行状态这个概念不理解,但是反射机制的前提就是在运行状态中,所以也必须搞清楚这个概念。 JAVA运行状态:所谓运行状态就是程序已经跑起来了,什么样叫跑起来了? 1、如果用m...

浮躁的码农
2016/02/01
38
0
浅析C#中的Attribute

最近用到了,所以静下心来找些资料看了一下,终于把这东西搞清楚了。 一.什么是Attribute 先看下面的三段代码: 1.自定义Attribute类:VersionAttribute [AttributeUsage(AttributeTargets.C...

Contac
2016/12/20
16
0
Java Annotation浅析

什么是Annotation (1)注解不是程序本身(也就是说Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的行),可以对程序作出解释(和注释没区别)(2)可以被其他程序...

wjk_snail
2016/01/05
53
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
54分钟前
3
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
6
0
IC-CAD Methodology知识图谱

CAD (Computer Aided Design),计算机辅助设计,指利用计算机及其图形设备帮助设计人员进行设计工作,这个定义同样可以用来近似描述IC公司CAD工程师这个岗位的工作。 早期IC公司的CAD岗位最初...

李艳青1987
今天
6
0
CompletableFuture get方法一直阻塞或抛出TimeoutException

问题描述 最近刚刚上线的服务突然抛出大量的TimeoutException,查询后发现是使用了CompletableFuture,并且在执行future.get(5, TimeUnit.SECONDS);时抛出了TimeoutException异常,导致接口响...

xiaolyuh
今天
5
0
dubbo 搭建与使用

官网:http://dubbo.apache.org/en-us/ 一,安装监控中心(可以不安装) admin管理控制台,monitor监控中心 下载 bubbo ops 这个是新版的,需要node.js环境,我没有就用老版的了...

小兵胖胖
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部