C#------反射

反射,顾名思义,即从一个对象的外部去了解这个对象(或程序集)的内部结构。尽管不知道这个对象是什么东西

反射,是 .NET中的重要机制,通过反射,可以再运行时获得程序或者程序集中每一个类型(包括类,委托,结构,接口和枚举等)的成员和成员的信息。

反射的用途

(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例

(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取定义在模块上的所有全局方法和其他特定的非全局方法

(3)使用ConstructInfo了解构造函数的名称,参数,访问修饰符和实现详细信息等

(4)使用MethodInfo了解方法的名称,返回值类型,参数,访问修饰符和实现详细信息等

(5)使用FeildInfo了解字段的名称,访问修饰符和实现详细信息等,并获取或设置字段值

(6)使用EventInfo了解事件的名称,事件处理程序数据类型,自定义属性,声明类型和反射类型等,添加或移除事件处理程序

 

(7)使用PropertyInfo了解属性的名称,数据类型,声明类型,反射类型和只读或可写状态等,获取或设置属性值

 

(8)使用ParamaterInfo了解参数的名称,数据类型,是输出参数还是输入参数,以及参数在方法签名中的位置等

 

System.Type类:


    System.Type 类对于反射起着核心的作用。但它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。

 

Type类的属性:


        Name 数据类型名


        FullName 数据类型的完全限定名(包括命名空间名)


        Namespace 定义数据类型的命名空间名


        IsAbstract 指示该类型是否是抽象类型


        IsArray   指示该类型是否是数组


        IsClass   指示该类型是否是类


        IsEnum   指示该类型是否是枚举


        IsInterface    指示该类型是否是接口


        IsPublic 指示该类型是否是公有的


        IsSealed 指示该类型是否是密封类


        IsValueType 指示该类型是否是值类型

 

Type类的方法:


        GetConstructor(), GetConstructors():返回ConstructorInfo类型,用于取得该类的构造函数的信息


        GetEvent(), GetEvents():返回EventInfo类型,用于取得该类的事件的信息


        GetField(), GetFields():返回FieldInfo类型,用于取得该类的字段(成员变量)的信息


        GetInterface(), GetInterfaces():返回InterfaceInfo类型,用于取得该类实现的接口的信息


        GetMember(), GetMembers():返回MemberInfo类型,用于取得该类的所有成员的信息


        GetMethod(), GetMethods():返回MethodInfo类型,用于取得该类的方法的信息


        GetProperty(), GetProperties():返回PropertyInfo类型,用于取得该类的属性的信息


    可以调用这些成员,其方式是调用Type的InvokeMember()方法,或者调用MethodInfo, PropertyInfo和其他类的Invoke()方法

 

 查看类中的构造方法:
      

 1  NewClassw nc = new NewClassw();
 2         Type t = nc.GetType();
 3         ConstructorInfo[] ci = t.GetConstructors();    //获取类的所有构造函数
 4         foreach (ConstructorInfo c in ci) //遍历每一个构造函数
 5         {
 6             ParameterInfo[] ps = c.GetParameters();    //取出每个构造函数的所有参数
 7             foreach (ParameterInfo pi in ps)   //遍历并打印所该构造函数的所有参数
 8             {
 9                 Console.Write(pi.ParameterType.ToString()+" "+pi.Name+",");
10             }
11             Console.WriteLine();
12         }

 


   

用构造函数动态生成对象:

 

 

 1 Type t = typeof(NewClassw);
 2         Type[] pt = new Type[2];
 3         pt[0] = typeof(string);
 4         pt[1] = typeof(string);
 5         //根据参数类型获取构造函数 
 6         ConstructorInfo ci = t.GetConstructor(pt); 
 7         //构造Object数组,作为构造函数的输入参数 
 8         object[] obj = new object[2]{"grayworm","hi.baidu.com/grayworm"};   
 9         //调用构造函数生成对象 
10         object o = ci.Invoke(obj);    
11         //调用生成的对象的方法测试是否对象生成成功 
12         //((NewClassw)o).show();    

 

 

用activator生成对象:

 

1 Type t = typeof(NewClassw);
2         //构造函数的参数 
3         object[] obj = new object[2] { "grayworm", "hi.baidu.com/grayworm" };   
4         //用Activator的CreateInstance静态方法,生成新对象 
5         object o = Activator.CreateInstance(t,"grayworm","hi.baidu.com/grayworm"); 
6         //((NewClassw)o).show();

 

 

查看类中的属性:

1 NewClassw nc = new NewClassw();
2         Type t = nc.GetType();
3         PropertyInfo[] pis = t.GetProperties();
4         foreach(PropertyInfo pi in pis)
5         {
6             Console.WriteLine(pi.Name);
7         }

 

查看类中的public方法:

 

1 NewClassw nc = new NewClassw();
2         Type t = nc.GetType();
3         MethodInfo[] mis = t.GetMethods();
4         foreach (MethodInfo mi in mis)
5         {
6             Console.WriteLine(mi.ReturnType+" "+mi.Name);
7         }

 

 

查看类中public字段:

 

1 NewClassw nc = new NewClassw();
2         Type t = nc.GetType();
3         FieldInfo[] fis = t.GetFields();
4         foreach (FieldInfo fi in fis)
5         {
6             Console.WriteLine(fi.Name);
7         }

 

 

用反射生成对象,并调用属性、方法和字段进行操作:

 

 1 NewClassw nc = new NewClassw();
 2         Type t = nc.GetType();
 3         object obj = Activator.CreateInstance(t);
 4         //取得ID字段 
 5         FieldInfo fi = t.GetField("ID");
 6         //给ID字段赋值 
 7         fi.SetValue(obj, "k001");
 8         //取得MyName属性 
 9         PropertyInfo pi1 = t.GetProperty("MyName");
10         //给MyName属性赋值 
11         pi1.SetValue(obj, "grayworm", null);
12         PropertyInfo pi2 = t.GetProperty("MyInfo");
13         pi2.SetValue(obj, "hi.baidu.com/grayworm", null);
14         //取得show方法 
15         MethodInfo mi = t.GetMethod("show");
16         //调用show方法 
17         mi.Invoke(obj, null);

 

 

System.Reflection.Assembly类 


     Assembly类可以获得程序集的信息,也可以动态的加载程序集,以及在程序集中查找类型信息,并创建该类型的实例


    使用Assembly类可以降低程序集之间的耦合,有利于软件结构的合理化

 

  通过程序集名称返回Assembly对象


        Assembly ass = Assembly.Load("ClassLibrary831");


     通过DLL文件名称返回Assembly对象


        Assembly ass = Assembly.LoadFrom("ClassLibrary831.dll");

 

     通过Assembly获取程序集中类


        Type t = ass.GetType("ClassLibrary831.NewClass");   //参数必须是类的全名


     通过Assembly获取程序集中所有的类


        Type[] t = ass.GetTypes();

 

posted @ 2017-10-13 15:39  吴祥锋  阅读(139)  评论(0)    收藏  举报