1.使用元数据完整的描述类型(接口、类、结构、委托、枚举)的能力是.net平台的一个关键要素。
2.反射:是一个运行库类型发现的过程
通过反射可以得到一个给定的*.dll获取*.exe程序集所包含的所有类型的列表,这个列表包含给定类型定义的方法、字段、属性和事件。主要在System.Reflection命名空间。
3.System.Type类
System.Type类定义了很多成员,可以用来检查某个类型的元数据,他们返回的类型大多位于System.Reflection命名空间中。
System.Type主要成员
IsAbstract、IsClass、IsValueType、IsSealed、IsInterface.....这些属性,可以用来发现类型的一些基本信息
GetEvents()、GetFields()、GetInterface()、GetMembers()、GetMethods()、GetProperties() ...这些方法获取类型的相关的信息数组,每个方法都有单独的版本,通过指定参数获取指定的项
FindMembers() 该方法查询返回一个MemberInfo类型的数组
GetType() 该静态方法返回一个Type实例
InvokeMember() 该方法运行对给定项目的晚期绑定
4.System.Reflection命名空间主要成员
Assembly : 该抽象类包含了许多静态方法,通过它可以加载、了解和操作一个程序集。
AssemblyName:该类可以找到隐藏在程序集的身份中的细节
EventInfo:该抽象类保存给定事件的信息
FieldInfo:该抽象类保存给定字段的信息
MemberInfo:抽象基类,它为EventInfo、FieldInfo、MethodInfo和PropertyInfo类型定义了公共的行为。
MethodInfo:该抽象类包含给定的方法的信息
Module:该抽象类可以使你访问多文件程序集中的给定模块
ParameterInfo:该类保存给定参数的信息
PropertyInfo:该抽象类保存给定属性的信息
5.得到Type引用
private void Func1()
{
Class1 cls1 = new Class1();
Type type = cls1.GetType();
Type type1 = typeof(Class1);
Type type2 = Type.GetType("ClassLibrary11.Class1", false, false); //使用静态方法获取类型信息,第一个参数传入类型的完全限定名,这里没有传入所在的程序集信息,类型被认为是定义在当前执行的程序集中的。如果获取外部私有程序集中的成员,字符串类型必须使用类型完全限定名加上类型所在的程序集的友好名称(用逗号隔开);第二个参数指定如果没有找到是否抛出异常;第三个参数指定查找时是否忽略大小写。
Type type3 = Type.GetType("ClassLibrary11.Class1,ClassLibrary11", false, true);
Type type4 = Type.GetType("ClassLibrary11.Class1+InnerClass1"); //使用+号获取一个嵌套类型,这里获取嵌套在Class1中的InnerClass1类型。
}
6.反射方法
public void ListMetheds(Type type)
{
MethodInfo[] mi = type.GetMethods();
foreach (var item in mi)
{
//
bool isFinal = item.IsFinal;
}
}
使用LINQ查询类型中的方法:
public void ListMetheds2(Type type)
{
var Metheds = from a in type.GetMethods() select a;
foreach (var item in Metheds)
{
//item.IsAbstract
}
}
7.反射字段、属性、实现的接口
var Fields = from a in type.GetFields() select a;
var Props = from a in type.GetProperties() select a;
var Interfaces = from a in type.GetInterfaces() select a;
8.Type.GetType()反射泛型类型
如果调用Type.GetType()来获取泛型类型的元数据描述,就必须使用“反钩号”加上数字值的语法来表示类型支持的类型参数个数。
如希望反射System.Collections.Generic.List<T>元数据描述,需要传入一下字符串
System.Collections.Generic.List`1
9.反射方法参数和返回值
public void ListMetheds2(Type type)
{
var Metheds = from a in type.GetMethods() select a;
foreach (var item in Metheds)
{
string returnInfo = item.ReturnType.FullName; //获取函数返回值类型
ParameterInfo[] ParaInfos = item.GetParameters(); //获取参数列表
}
}
10.动态加载程序集
System.Reflection定义了Assembly的类,使用这个类,我们可以动态加载程序集,并获取程序集内部的信息。
Assembly的静态方法Load()仅传入一个要加载到内存的程序集的友好名称,但是需要将程序集复制到当前应用程序的相同目录。
Assembly的静态方法LoadFrom()传入一个要查看的程序集的绝对路径(更常用)。
11.晚期绑定
晚期绑定是一种创建给定类型的实例并在运行是调用其成员,而不需要在编译时知道它存在的一种技术。晚期绑定对于程序的可扩展性来说至关重要。
12.System.Activator类
该类是.net晚期绑定过程中的关键所在。
Activator.CreateInstance()该方法建立一个晚期绑定类型的实例,有多个重载版本。
public void CreateInstanceFromAssembly(Assembly asm)
{
try
{
Type type = asm.GetType("ConsoleApplication3.Class1");
object obj = Activator.CreateInstance(type); //创建实例
MethodInfo mi = type.GetMethod("GetId");
mi.Invoke(obj, null); //用指定的参数调用当前实例所表示的方法,null意味着没有参数
MethodInfo mi2 = type.GetMethod("SetId");
mi2.Invoke(obj, new object[] { 2 }); //调用有参数函数,参数为对象集合,依次传入
}
catch (Exception ex)
{
}
}