反射实例及概念

Posted jason-365

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射实例及概念相关的知识,希望对你有一定的参考价值。

反射:

  Relection,中文翻译为反射,这是。NET 中获取运行时类型信息的方式。

  。net的应用程序由几个部分:‘程序集’,‘模块’,‘类型’组成,而反射提供一种编程方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,

例如:

  assembly类可以获得正在运行的装配件信息,也可以动态加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。

  Type类可以获得对象的 类型信息,此信息包含对象的所有要素:方法、 构造器、 属性等等,通过Type类可以得到这些要素的信息,并且调用之。

  MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。还有FIeldInfo(字段)、EventInfo(事件)。。。

  这些类都包含在System.Relection命名空间下。

 

  程序用来处理数据的,文泵和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据。

  有关程序及其类型的数据被称为元数据(metadata),它们是保存在程序的程序集中。

  反射:

    程序在运行时,可一个查看其它程序集或其本身的元数据,一个运行的程序查看本身的元数据或者其它程序集的元数据的行为。

    反射提供了描述程序集,模块和类型的对象(Type类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段

    和属性,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口、枚举)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以                直接创建对象,即使这个对象的类型在编译时还不知道。下面是使用静态方法GetType(从Object基类派生的所有类型都继承该方法)获取变量类型的简单反射实例:

  int i= 42;

  System.Type type = i.GeType();

  System.Console.WriteLine(type);

 

特性的概念和用法

  特性(Attribute)用于在运行时传递程序中的各种元素(比如类、 方法、 结构、 枚举、 组件、等)的行为信息的声明性标签。您可以通过使用特性向程序添加性信息。一个声明性标签是通过放置在它所应用的元素前面括号(【】)来描述的。

  特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net提供了两种类型的特性:预定义特性和自定义特性。

 

  规定特性:【attribute(positoinal_parameters,name_parameter = vale,.........)】

        element

    特性的名称和值是放在括号内规定的,放置在它所应用的元素之前。positional_parameters 规定必须的信息,name_parameter规定可选的信息。

  

  预定义特性(Attribute)

    》.Net框架提供了三种预定义的特性:

    》AttributeUsage : 规定了特性可应用到的项目类型。

      【AttributeUsage(

          validon,    规定特性可被放置的语言元素,是枚举器AttributeTargets的值得组合。默认值是AttributeTargets.All.

          AllowMultiple = allowmultiple, (可选的)  为该特性的AllowMultiple属性(property)提供一个布尔值。如果为true,则该属性是多用的;

                                                         如果为false,则该属性是单用的。

          Inherited = inherited (可选的) 为该特性提供一个bool值,如果为true,则该特性可被派生类继承。默认是false(不被继承)

      )】

    》Conditional  : 这个预定义特性标记了一个条件方法,其执行依赖于它项的预处理标示符。它会引起方法调用的条件编译,取决于指定的值,比如Debug或Trace。例如:                                          当调试时显示变量的值。

      【Conditional(

          conditionalSymbol                     Conditional("DEBUG")

      )】

 

    》Obsolete:标记了不应被使用的程序实体。他可以让您通知编译器丢弃某个特定的目标元素。例如:当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个使用新方法,而不是旧方法的消息,来把它标记为obsolete(过时的)。

      

       【Obsolete(

          meesage

        )】

        [Obsolete(

          message,  是一个字符串,描述项目为什么过时的原因以及该替代使用什么。

          iserror  是一个布尔值,如果为true,编译器应把该项目的使用当做一个错误,默认值是false(编译器生成一个警告)

        )]

   创建自定义特性(Attribute)

      Net框架允许创建自定义特性,用于存储声明性的信息,且可在运行时被检索。该信息根据设计标准和应用程序需要,可与任何目标元素相关。

      创建并使用自定义 特性包含四个步骤:

        》声明自定义特性

        》构建自定义特性

        》在目标程序元素上应用定义特性

        》通过反射访问特性

      最后一个步骤包含一个简单的程序来读取元数据以便查找各种符号。元数据是用于描述其他数据的数据和信息。该程序应使用反射来在运行时访问特性。

         //一个自定义特性 BugFix 被赋给类及其成员

          

 [AttributeUsage(AttributeTargets.Class|
            AttributeTargets.Constructor |
            AttributeTargets.Field|
            AttributeTargets.Method|
            AttributeTargets.Property,
            AllowMultiple = true
            )]
            public class DeBugInfo: System.AttributeTargets

  我们在源代码中将特性应用于程序结构:

    编译器获取源代码并且从特性产生元数据,然后把元数据放到程序集中;

    消费者程序可以获取特性的元数据以及程序中其他组件的元数据。注意,编译器同时生产和消费特性。

    关于特性的命名规范,特性名使用Pascal命名法(首字母大写),并且Attribute后缀结尾,当目标应用特性时,我们可以不使用后缀。例如SerializableAttribute和                                 MyAttribuetAttribute这两个特性,我们把他们应用到结构是可以使用Serializable和MyAttribute.

应用特性:

    目的:告诉编译器把程序结构的某组元数据嵌入程序集。我们可以通过吧特性应用到结构来实现。

       在结构前放置特性片段来应用特性:

       特性片段被方括号包围,特性片段包括特姓名和特性的参数列表;

       应用了特性的结构成为特性装饰。

    其他预定义特性:

        特性         意义

      CLSCompliant     声明可以公开的成员应该被编译器检查是否符合CLS。兼容的程序可以被任何。NET兼容的语言使用

      Serializable    声明结构可以被序列化

      NonSerialized   声明结构不可以被序列化

      DLL mport         声明是非托管代码实现的

      WebMethod    声明方法应该被作为XML Web服务的一部分暴露

      AttributeUsage   声明性能应用到什么类型的程序结构。将这个特性应用到特性声明上

      Assembly                         全局特性

 

以上是关于反射实例及概念的主要内容,如果未能解决你的问题,请参考以下文章

C#反射实例学习及注意内容

Java反射机制

OpenGL片段着色器不照亮场景

Golang实践录:反射reflect的一些研究及代码汇总

java 反射代码片段

Java程序语言的后门-反射机制