反射:
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 全局特性