文档章节

浅析.NET的反射特性

彭泽0902
 彭泽0902
发布于 2016/11/24 18:47
字数 1184
阅读 5
收藏 0
点赞 0
评论 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 ⋅ 33

Instant Run 浅析

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

Jason's Blog ⋅ 2015/11/24 ⋅ 0

Java 反射机制浅析(重要)

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

浮躁的码农 ⋅ 2016/02/01 ⋅ 0

浅析C#中的Attribute

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

Contac ⋅ 2016/12/20 ⋅ 0

Java Annotation浅析

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

wjk_snail ⋅ 2016/01/05 ⋅ 0

java注解浅析

了解注解 我们有必要对JDK 5.0新增的注解(Annotation)技术进行简单的学习,因为Spring 支持@AspectJ,而@AspectJ本身就是基于JDK 5.0的注解技术。所以学习JDK 5.0的注解知识有助于我们更好...

wangrikui ⋅ 2015/09/06 ⋅ 0

关于xss几点见闻

浅谈反射型XSS的利用 转自鬼仔: |=---------------------------------------------------------------------------=| |=-------------------------=[ 浅谈反射型XSS的利用 ]=--------------......

氪金 ⋅ 2012/10/11 ⋅ 0

java基础-反射浅析(磨砺营马剑威java)

【威哥说】本文里波波老师将带领大家一起学习一下什么是反射,文中暂且没有详细给大家介绍反射如何去获取类中的所有属性和方法,更多的是介绍什么场景下会使用到反射,使用反射有什么好处和缺...

磨砺营 ⋅ 2016/09/05 ⋅ 0

Java系列文章(全)

JVM JVM系列:类装载器的体系结构 JVM系列:Class文件检验器 JVM系列:安全管理器 JVM系列:策略文件 Java垃圾回收机制 深入剖析Classloader(一)--类的主动使用与被动使用 深入剖析Classloader(二...

www19 ⋅ 2017/07/04 ⋅ 0

nodejs POST加号变成了空格

今天在写post的时候,post的数据是用加号拼的一个字符串然后在服务上我要split分成数组可是怎么也没有成功 然后我打印出字符串竟然没有+号了,变成空格了 我还以为是+写成什么特殊的显示不出...

hongyi1159 ⋅ 2017/05/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

十五周二次课

十五周二次课 17.1mysql主从介绍 17.2准备工作 17.3配置主 17.4配置从 17.5测试主从同步 17.1mysql主从介绍 MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主...

河图再现 ⋅ 55分钟前 ⋅ 0

docker安装snmp rrdtool环境

以Ubuntu16:04作为基础版本 docker pull ubuntu:16.04 启动一个容器 docker run -d -i -t --name flow_mete ubuntu:16.04 bash 进入容器 docker exec -it flow_mete bash cd ~ 安装基本软件 ......

messud4312 ⋅ 今天 ⋅ 0

OSChina 周一乱弹 —— 快别开心了,你还没有女友呢。

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享吴彤的单曲《好春光》 《好春光》- 吴彤 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :小萝莉街上乱跑,误把我认错成...

小小编辑 ⋅ 今天 ⋅ 7

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部