反射:访问程序集中类型的元数据,其中包括像完整类型名和成员名这样的构造,以及对一个构造进行修饰的任何特性。
通俗点将就是可以通过object.GetType()或typeof()方法来得到一个变量的Type类型,然后获取该类型数据的所有属性、方法以及特性。
反射是指对该类型数据内所有属性、方法和特性进行检查访问的过程。
可以通过object.GetType()或typeof()方法来获取数据类型;
通过Type.GetProperties()方法来获取数据类型内的属性;
通过Type.GetMethods()方法来获取数据类型内的方法;
通过Type.GetFields()方法来获取数据类型内的字段;
通过Type.IsPublic来获取数据类型是否为Public的;
通过Type.BaseType来得到数据类型的基类;
通过Type.GetInterFaces()来获取数据类型支持的接口;
以及通过Type.GetCustomAttributes()方法来获取都有什么特性在修饰一个类型。
(注意GetMethods()不能返回拓展方法,拓展方法只能作为实现类型的静态成员使用)
1.GetType()
object包含一个GetType()成员,因此所有类型都可以通过调用GetType()来获取对象的System.Type实例。
例如:DateTime data = new DateTime(); Type type = data.GetType();
获取到对象的System.Type实例后可以遍历Type.GetProperties()返回的每个System.Reflection.PropertyInfo实例并显示属性名。注意成功调用GetType()的关键在于获得一个对象实例,但有时这样的实例无法获得,例如静态类无法实例化,无法调用GetType()。
2.typeof()
获得Type对象的另一个方法是使用typeof表达式。typeof在编译时绑定到特定的Type实例,并直接获取类型作为参数。
例如:ThreadPriorityLevel priority; Type type = typeof(ThreadPriorityLevel);
3.成员调用
反射并非仅可用于获取元数据,下一步是获取元数据并动态调用它引用的成员。
PropertyInfo property = itemData.GetType().GetProperty("Name",
BindingFlags.IgnoreCase |
BindingFlags.Instance |
BindingFlags.Public);
if(property != null)
{
if(property.PropertyType == typeof(string))
{
property.SetValue(itemData, "Test");
}
if(property.PropertyType == typeof(int))
{
property.SetValue(itemData, 10);
}
}
上述代码中通过GetProperty()方法找到一个同名的实例属性,然后通过SetValue()方法来给属性赋值,SetValue()的参数包括要设置值的对象、新值以及一个额外的index参数(除非属性位索引器,否则参数为null或不填)。
4.泛型类型上的反射--判断泛型参数的类型
可以对泛型类型或泛型方法中的类型参数使用typeof()来获取System.Type的实例。
例如:
public class Stack<T>
{
//*****
public void Add(T i)
{
//***
System.Type type = typeof(T);
//***
}
//*****
}
获取到类型参数的Type对象实例后,就可以在类型参数上执行反射,从而判断它的行为,并针对具体类型来调整Add方法,使其能更有效地支持这种类型。
5.判断类或方法是否支持泛型
可查询Type.ContainsGenericParameters属性判断类或方法是否包含尚未设置的泛型参数。
Type.IsGenericType是指示类型是否泛型的Boolean属性。
6.为泛型类或方法获取类型参数
可调用GetGenericArguments()方法从泛型类获取泛型参数的列表。这样得到的是由System.Type实例构成的一个数组,这些实例的顺序就是它们作为泛型类的类型参数被声明的顺序。
例如:
public void Main()
{
Stack<int> s = new Stack<int>();
System.Type t = s.GetType();
foreach (System.Type type in t.GetGenericArguments())
{
Debug.Log("Type parameter:" + type.FullName);
}
}