反射:本人比木乃,是哪位大师详细讲解反射是个什么东西,能看得见,摸得着吗。怎么用,什么时候用,具体用法。最好用通俗易懂的话讲解哈
指程序可以访问、检测和修改它本身状态或行为的一种能力,程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。反射通常具有以下用途:
1.使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
2.使用 Module 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
3.使用 ConstructorInfo 了解如下的类似信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。
4.使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
5.使用 MethodInfo 来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。
6.使用 FieldInfo 来了解如下的类似信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
7.使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
8.使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
9.使用 ParameterInfo 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
调用代码,自行百度,我说说他干嘛用的:
如果我给你一个类源文件xxx.java,里面封装了若干public函数,你要调用这些函数很简单,在其他类里面直接import这个类,然后直接调用就可以了
但是现在我不直接给你这个类的源文件,而是把字节码文件xxx.class给你,那个函数你怎么调用?反射就是解决这个问题的,有了类的class文件,并且
知道里面的函数名和参数类型,就可以用反射去调用这个函数,这样的话如果你以后写了什么功能模块给别人用,你又不想让别人知道你的源码怎么
实现的,ok,把编译后的class给他,然后再把函数的原型给他,他就可以通过反射来使用你的模块
反射简单来说就是RTTI(运行时刻类型识别)和DC(动态创建)。
RTTI的典型应用场景:比如说Visual Studio能列举出你引用的某个动态库中都有什么函数,参数是什么,这个动态库显然事先VS不知道它的存在。是运行的时候获取它的类型信息。这个就是RTTI
DC的场景:比如你把一个控件拖动到窗体上,VS同样就创建了一个控件的实例,这个过程就是动态创建。另外很多程序支持插件,允许你在运行的时候调用一个插件的函数,显然插件也是开发程序的时候不可能遇见它的存在的。这就是动态创建。
可以看看这篇文章:《什么是反射》http://blog.csdn.net/dawanganban/article/details/28666775
说下鄙人的感悟:如果说程序运行,是一个编译到执行的过程,那么反射就是把执行中的东西反向成编译的东西,甚至更进一步变成代码期的东西。说白了就是把已经编译成2进制的机器语言重新解释成汇编或者高级语言,让我们可以动态的再次修改它、调整它,再编译执行。
当我们需要在运行期动态的 增删改查 程序设计期的东西时,就可以用到反射。。。用java举个例子:有一个对象User,里面有属性name、password。我要在程序运行过程中获得name和password。通常我们可以通过User的get方法获取,但同时我们可以通过反射获得User的所有Field(属性)。。。现在做一个有趣的设想,有一个对象Object,我们不知道它是什么,可能是Cat、也可能是School,甚至Fly。但是我们要获得这个对象的所有属性,把它所有的属性都取出来。(例如,由于存储)。。。这个时候反射就爽了,直接通过Object获得所有Field就可以了。
再例如,现在有一堆对象:人、工人、学生、老师、教授。。。我们不知道那些对象中有city(所在城市)这个属性,甚至不知道那个对象中有没有。但是有一个需求,我要把有city属性的所有对象的city都改成“北京”。这个时候如果不用反射,大家想想,你改怎么做,得多麻烦。。。但是有反射后,直接遍历所有Object的Field,只要发现Field是City,直接改成“北京”就ok了。这样,方便吧。
推荐一本书,《Ruby元编程》。
通过当前是对象去找对应类的信息,还可以创建对象等.
主要运用类型类的对象的一些操作.
程序本来是人写好,机器运行,
反射就是机器写程序,然后机器自己运行
把实例化哪个对象延迟到运行时决定
来个最简单, 最实用的吧:
一个类: Student , 两个属性 Id , Name
对应表: Student, 两个字段 Id, Name
在连接数据库, 而且需要将其赋值, 其过程容易吗?
其实也容易
obj.Id = Convert.ToInt32(dr["Id"]);
obj.Name = Convert.ToString(dr["Name"]);
但如果有一千个表, 一千个字段, 要一行一行地写也挺不容易,
于是你可以用反射, 在赋值时用反射来遍历每个属性, 根据名称和属性本身的类型来赋值就可以了。