程序正在运行时,可以查看其它程序集或者自身的元数据。一个运行的程序查看本身或者其它程序的元数据的行为就叫做反射。
在程序运行时,通过反射可以得到其它程序集或者自己程序集代码的各种信息类,函数,变量,对象等等,实例化它们,执行它们,操作它们。
射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外还可以直接创建对象,即使这个对象的类型在编译时还不知道。
C#中的反射可以完成以下任务:
- 枚举类型的成员;
- 实例化新对象;
- 执行对象的成员;
- 查找类型的信息;
- 查找程序集的信息;
- 检查应用于某种类型的定制特性;
- 创建和编译新程序集。
C#中的反射主要通过 System.Type 和 System.Reflection.Assembly 两个类来实现的。
System.Type 类定义了很多成员,可以用来检查某个类型的元数据,它们返回的类型大多位于System.Reflection命名空间中。Type类只用来存储类型的引用。
我们以前把Type看作一个类,但实际上是一个抽象的基类。
只要实例化了一个Type对象,实际上就实例化了Type的一个派生类。
尽管在一般情况下派生类只提供各种Type方法和属性的不同载体,但是这些方法和属性返回对应数据类型的正确数据。
通常,获取指向任何给定类型的Type引用有3种常用方式。
static void Main(string[] args)
{
string s = "111";
int i = 123;
//第一种获取类型(Type)的方式
Type t=typeof(string);
Type t1=typeof(int);
Type t2=typeof(Action);
//第二种,可以直接用任意对象.GetType()来获取他们的类型
t=s.GetType();
t1 = (123).GetType();
Action a = (() => { Console.WriteLine("aaaaaa"); });
t2.Assembly.GetType();
//第三种,可以直接将元数据类型通过Type去声明
t = Type.GetType("System.String");
Console.WriteLine(t);
Console.WriteLine(t1);
Console.WriteLine(t2);
}
Type的属性:
Name获取数据类型名
FullName 获取类型的完全限定名(包括命名空间名)
Namespace 获取包含类的命名空间
Console.WriteLine(tt.Name);
Console.WriteLine(tt.FullName);
Console.WriteLine(tt.Namespace);
还有一些布尔类型的属性指明这种类型是一个类,还是一个枚举等特性
IsAbstract 指明类型是否是抽象的
IsArray 指明类型是否是数组
IsClass 指明类型是否是一个类
IsEnum 指明类型是否是一个枚举
IsInterface 指明类型是否是一个接口
IsPublic 指明类型是否是公有的
IsSealed 指明类型是否被声明为密封的
IsValueType 指明类型是否是值类型
//获取一个类型
Type tt = typeof(Person);
Console.WriteLine("是不是抽象类:" + tt.IsAbstract);
Console.WriteLine("是不是类:" + tt.IsClass);
Console.WriteLine("是不是接口:" + ttt.IsInterface);
Type的方法
System.Type的大多数方法都用于获取对应数据类型的成员信息:构造函数、属性、方法和事件等。
有两个方法可以获取数据类型的方法的细节信息:GetMethod()和GetMethods()。GetMethod()方法返回System.Reflection.MethodInfo对象的一个引用,其中包含一个方法的信息。
GetMethods()方法返回这种引用的一个数组。这两个方法都有重载的版本,重载方法有一个附加的参数,即BindingFlags枚举值,该值表示返回哪些成员,列如,返回公有成员、实例成员和静态成员等。
返回类型 | 方法 | 说明 |
---|---|---|
FieldInfoGetField() | GetFields() | 获取类型中的字段 |
MethodInfoGetMethod() | GetMethods() | 获取类型中的方法 |
PropertyInfoGetProperty() | GetProperties() | 获取类型中的属性 |
//获取类型中包含的所有方法
MethodInfo[] list = tt.GetMethods();
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.WriteLine("_________________属性______________________");
//获取类型中包含的所有属性
foreach (var item in tt.GetProperties())
{
Console.WriteLine(item);
}