




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Good is good, but better carries it.精益求精,善益求善。C_参考:反射_-_学习笔记整理,概念与应用-C#参考:反射-学习笔记整理,概念与应用1.什么是反射Reflection,中文翻译为反射。这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:程序集(Assembly)、模块(Module)、类型(class)组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:通常程序员面试题,有这样关于反射的解释:反射可以动态地创建类型的实例,还可以将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型
2、的方法或访问其字段和属性。Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。诸如此类,还有FieldInfo、PropertyInfo、ConstructorInfo、EventInfo等等,这些类都包含在System.Reflection命名空间。2.命名空间与装配件的关系很多人对这个概念可能还
3、是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。命名空间类似与Java的包,但又不完全等同,因为Java的包必须按照目录结构来放置,命名空间则不需要。核心语:装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在,这样说可能有点模糊,举个例子:装配件A:namespaceN1publicclassAC1publicclassAC2namespaceN2publicclassAC3publicclassAC4装配件B:namespaceN1
4、publicclassBC1publicclassBC2namespaceN2publicclassBC3publicclassBC4这两个装配件中都有N1和N2两个命名空间,而且各声明了两个类,这样是完全可以的,然后我们在一个应用程序中引用装配件A,那么在这个应用程序中,我们能看到N1下面的类为AC1和AC2,N2下面的类为AC3和AC4。接着我们去掉对A的引用,加上对B的引用,那么我们在这个应用程序下能看到的N1下面的类变成了BC1和BC2,N2下面也一样。如果我们同时引用这两个装配件,那么N1下面我们就能看到四个类:AC1、AC2、BC1和BC2。到这里,我们可以清楚一个概念了,命名空间
5、只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。上面我们说了,装配件是一个类型居住的地方,那么在一个程序中要使用一个类,就必须告诉编译器这个类住在哪儿,编译器才能找到它,也就是说必须引用该装配件。问题出现了:如果在编写程序的时候,也许不确定这个类在哪里,仅仅只是知道它的名称,就不能使用了吗?答案是可以,这就是反射了,就是在程序运行的时候提供该类型(class)的全地址,而去找到它。3.运行期得到类型信息有什么用?有人也许疑问,既然在开发时就能够写好代码,干
6、嘛还放到运行期去做,不光繁琐,而且效率也受影响。这就是个见仁见智的问题了,就跟早绑定和晚绑定一样,应用到不同的场合。有的人反对晚绑定,理由是损耗效率,但是很多人在享受虚函数带来的好处的时侯还没有意识到他已经用上了晚绑定。这个问题说开去,不是三言两语能讲清楚的,所以就点到为止了。我的看法是,晚绑定能够带来很多设计上的便利,合适的使用能够大大提高程序的复用性和灵活性,但是任何东西都有两面性,使用的时侯,需要再三衡量。接着说,运行期得到类型信息到底有什么用呢?还是举个例子来说明,很多软件开发者喜欢在自己的软件中留下一些接口,其他人可以编写一些插件(程序集(dll等)来扩充该软件的功能,比如我开发了一
7、个销售图书的电子商务系统,其中的两个业务一是:新增加购买订单;二是,根据订单的唯一标识号获取某一订单信息。我希望以后可以很方便的扩展到多种数据库管理系统中(MSSQLSERVER,Oracle等)来完成相关业务,那么我需要声明一个接口:/*/InterfacefortheOrderDAL/publicinterfaceIOrder/Property表示该系统业务采用什么类型的数据,MSSQLorOracle等等stringDataBaseTypeget;/*/Methodtoinsertanorderheader/Businessentityrepresentingtheorder/Order
8、IdvoidInsert(OrderInfoorder);/*/ReadstheorderinformationforagivenorderId/Uniqueidentifierforanorder/BusinessentityrepresentingtheorderOrderInfoGetOrder(intorderId);实体类(OrderInfo)/*/Businessentityusedtomodelanorder/publicclassOrderInfoprivateintorderId;privateDateTimedate;privatestringuserId;privates
9、tringorderNo;privatestringcourierWay;privatestringpaymentWay;/*/订单ID/publicintOrderIdgetreturnorderId;setorderId=value;/*/订单提交日期/publicDateTimeDategetreturndate;setdate=value;/*/用户ID/publicstringUserIdgetreturnuserId;setuserId=value;/*/订单编号/publicstringOrderNogetreturnorderNo;setorderNo=value;/*/配送方
10、式/publicstringCourierWaygetreturncourierWay;setcourierWay=value;/*/支付方式/publicstringPaymentWaygetreturnpaymentWay;setpaymentWay=value;这个接口中包含:(1)一个DataBaseType属性,这个属性返回扩展的或是要支持的数据库管理系统的标识或描述,这样就可以知道是使用那个数据库系统,根据Web.config提取相关了(不明白就往下走);(2)第一个方法(Insert(OrderInfoorder)(这里我定义了一个OrderInfo类(实体),这个类(实体对象)
11、提供对数据的封装,在这里,简单地说就是将订单的相关信息(见实体类中定义的属性),封装在该实体类创建的实体对象中,作为该插入(Insert)新纪录的参数。(3)第二个方法(GetOrder(intorderId)这个方法由提供的订单Id(orderId)从数据库中,读取相关数据,记录在创建的OrderInfo实体对象中,通过该实体对象的属性可以读取相关信息,如订单生成日期,金额,发送地址等;那么我规定所有的数据访问逻辑(基于基于某一数据库系统)都必须派生一个数据库访问层,并且实现这个接口,在定义的方法中返回处理处理Code对象,并且可以指定,数据库类型的描述(如DBMSName)。这样的话,我就
12、不需要在开发系统时知道将来需要采用的数据系统类型(是采用MsSqlServer呢?还是采用Oracle呢?等等),只需要从配置文件中获取现在所指定的数据库系统的描述,就可以动态的创建对象,将其转换为IOrder接口来使用。这就是反射的一个典型的应用,在.NETPetShop4.0中有重要使用这一方式。4.通过一个Demo演示,一个对象的实例泄漏的秘密(这是我从别人那看来的)classProgramstaticvoidMain(stringargs)classclassAinternalintiNumberA=100;publicintiNumberB=200;privateintpropert
13、y;publicintPropertygetreturnproperty;setproperty=value;publicvoidFunA()Console.WriteLine(classAisaFuction!);classclassBclassTestObjectTypeinternalvoidFucType(objectA)TypeobjType=A.GetType();Assemblyobjassembly=objType.Assembly;Typetypes=objassembly.GetTypes();foreach(Typetypeintypes)Console.WriteLin
14、e(类名+type.FullName);/获取类型的结构信息ConstructorInfomyConstructor=type.GetConstructors();Show(myConstructor);/获取类型的字段信息FieldInfomyField=type.GetFields();Show(myField);/获取方法的方法MethodInfomyMethod=type.GetMethods();Show(myMethod);/获取属性的方法PropertyInfomyProperty=type.GetProperties();Show(myProperty);/获取事件信息,这个D
15、emo没有事件,所以就不写了EventInfoConsole.ReadLine();/显示数组的基本信息privatevoidShow(objectmyObject)foreach(objectvarinmyObject)Console.WriteLine(var.ToString();Console.WriteLine(-);运行结果如下图所示:但是,测试分析后,发现其实也只能获得public类型的信息5.动态创建对象实例的基础是实现抽象工厂的基础,也是实现抽象工厂的核心技术,通过它,可以动态创建一个你想要的对象.如下面的例子是演示如何动态创建ChineseName或EnglishName的
16、实例。这个Demo和3中降到的Demo如出一辙,这个更简化些(用C#控制台应用程序编写的),并提供完整的动态创建对象的代码,读者对照两者揣摩加联系。其实都很简单。usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Reflection;namespaceTestReflectionclassProgramstaticvoidMain(stringargs)INameobjChineseName=AbstractFactory.createChineseName();objChineseName.Sho
17、wName();INameobjEnglishName=AbstractFactory.createChineseName();objEnglishName.ShowName();/声明一个接口,它有一个显示名字的功能(ShowName方法)publicinterfaceINamevoidShowName();/实现接口,显示中国名字publicclassChineseName:INameIName成员#regionIName成员publicvoidShowName()Console.WriteLine(我叫XX!);Console.ReadLine();#endregion/实现接口,显示中
18、国名字publicclassEnglishName:INameIName成员#regionIName成员publicvoidShowName()Console.WriteLine(MynameisXXa!);Console.ReadLine();#endregion/最为重要的代码段,往下看/使用抽象工厂的方法来进行动态创建对象实例应用哦publicsealedclassAbstractFactorypublicstaticreadonlystringpath=TestReflection;publicstaticINamecreateChineseName()/s的值以后从Web.Config动态读取,如下所示/*/*/把className赋值为:TestReflection.ChineseName,将显示中文名stringclassName=path+.ChineseName;return(IName)Assembly.Load(path).CreateInsta
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 偷钱自愿归还协议书范本
- 文化产业项目部分股权置换与转让实施合同
- 旅游景区开发项目诚意金支付及合作终止协议
- 产业园区物业管理与招商引资合作协议
- 仓储物流园区拆迁补偿及补偿款分配协议
- 生态工业园区绿色厂房租赁合同书
- 阿里巴巴平台消费者权益保护服务合同
- 中式快餐店跨区域联营管理协议
- 厂房搬迁及安全生产责任协议
- 施工记录填写培训
- 2024北京西城区四年级(下)期末数学试题及答案
- 中国慢性阻塞性肺疾病基层诊疗指南(2024年)解读
- 湖北省宜昌市(2024年-2025年小学三年级语文)部编版期末考试(下学期)试卷(含答案)
- 食物与药物的相互作用
- 规范申报专题培训-课件
- 精神病症状学(psychopathology)课件
- 华泰基本面轮动系列之七:行业配置策略趋势追踪视角
- “一站到底”知识竞赛题库及答案(1590题)
- GB∕T 19673.1-2013 滚动轴承 套筒型直线球轴承附件 第1部分 1、3系列外形尺寸和公差
- 亚马逊品牌授权书(英文模板)
- 《现代汉语修辞》PPT课件(完整版)
评论
0/150
提交评论