1.什么是反射及用途?
2.哪些情况下会用到反射?
3.反射在实际应用中是怎么用的?
我想弄明白这些问题,可能会对学习反射起到更为积极的作用.
反射是一种机制,这种机制可以让我们获取运行时类型信息.反射运用的比较广泛其中Spring的IOC容器就是通过读取配置文件,利用反射对接口进行实例化.要想清楚的了解反射需要知道,NET应用程序的组成.主要由以下几部分组成:程序集(Assembly),模块(Module),类型(Class).反射可以在程序运行时期得到这几部分的信息.从而达到生成实例进行调用的目的.
那么我们为什么要这样应用呢?这是决定我们是否需要使用反射的问题.试想一下,如果现在有两个不同的团队, A团队服责展现层与逻辑层的工作,而B团队服责持久层的工作.那么在实际情况下,B会提供给A一个DLL库文件供A使用.这样A就可以使用反射这种机制来调用DLL库,即使DLL库的内容改变了,A也不用修改什么.
现在有一个概念需要了解,命名空间与装配件的关系.命名空间就是你使用Using命令时写的一堆字符串,它会告诉程序你使用的类应该从哪里去引入.装配件是程序执行的最小单位,编译出来后是.DLL,.EXE文件这就是装配件.一个命名空间可以出现在多个装配件中,一个装配件可以拥有多个命名空间.如下:
装配件A.DLL
namespace N1
{
public class AN1{...}
public class AN2{...}
}
namespace H1
{
public class AH1{...}
public class AH2{...}
}
装配件B.DLL
namespace N1
{
public class BN1{...}
public class BN2{...}
}
namespace H1
{
public class BH1{...}
public class BH2{...}
}
这里所指的装配件通常是DLL文件.
动态获取类型的方法实际上并没有想像中那么难.
1.Object.GetType()方法,如果你已经获得到一个Object对象,那么你就可以通过GetType方法来取得一个Type的实例从而知道这个对象的一切信息了.
2.另外还有一种方法是使用Type的静态方法GetType(classType),classType是具体的类型名称.需要强调的是这里的classType就是上面所讲的命名空间+类名,比如需要得到String对象类型,那么可以这样写
Type t = Type.GetType("System.String");这里需要注意的是系统默认已经自动引入了这个命名空间所在DLL文件(装配件mscorlib.dll),所以像以上的写并没有什么问题.
Type t = Type.GetType("System.Data.DataTable");这一句在运行的时候就会出现错误,因为命名空间"System.Data.DataTable"所在的DLL文件(System.Data.dll)系统默认是不自动引入的.这时候就需要手动引入DLL文件又或者这样写
Type t = Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");同样你需要将DLL文件放到C#找的到的地方,否则同样会出错.
3.上面已经给出两种获取方法,还有第三种方法就是使用Assembly.GetType()方法.
此种方法首先需要获得一下Assembly的实例,Assembly asm=Assembly.Load("命名空间");这同样是在不需要引入DLL文件的时候使用.如果需要引入DLL文件可以这样使用 Assembly asm=Assembly.LoadFile(@"d:/Test.dll");
Type t = asm.GetType("命名空间+类名");
有了Type对象之后就可以自己创建实例,调用方法等.比如可以通过调用GetMethod方法来获取MethodInfo对象
通过Assembly实例的CreateInstance方法来获取对象实例
asm. CreateInstance(t,new object[]{"..."});//类型,对象初始化参数,如果没有可以不写
,在通过MethodInfo对象Invoke方法调用对象的方法时,如果是实例方法那么需要实例对象做参数,如果是静态方法置NULL就可以.
引用一个网上的例子
public void test1()
{
System.Reflection.Assembly ass;
Type type ;
object obj;
try
{
ass = System.Reflection.Assembly.LoadFile(@"d:/TestReflect.dll");
type = ass.GetType("Webtest.ReflectTest");//必须使用名称空间+类名称
System.Reflection.MethodInfo method = type.GetMethod("WriteString");//方法的名称
obj = ass.CreateInstance("Webtest.ReflectTest");//必须使用名称空间+类名称
string s = (string)method.Invoke(obj,new string[]{"jianglijun"}); //实例方法的调用
Response.Write(s+"<br>");
method = type.GetMethod("WriteName");//方法的名称
s = (string)method.Invoke(null,new string[]{"jianglijun"}); //静态方法的调用
Response.Write(s+"<br>");
method = type.GetMethod("WriteNoPara");//无参数的实例方法
s = (string)method.Invoke(obj,null);
Response.Write(s+"<br>");
method = null;
}
catch(Exception ex)
{
Response.Write(ex+"<br>");
}
finally
{
ass = null;
type = null;
obj = null;
}
}仅为个人学习,不做发表.
参考文章:http://www.crazycoder.cn/DotNet/Article20596.html
http://www.cnblogs.com/fineboy/archive/2006/10/10/525348.html
http://www.cnblogs.com/zhusl118/archive/2008/11/21/1338373.html
http://www.phpchinaz.cn/c/CSharp/52_5201_1230349985.html