.NET反射的简单理解
反射的一切都是围绕着“检查对象及其类型”展开的。一旦获取到一个Type对象的引用,就可以访问到与这个对象类型有关的所有信息,包括类的构造函数、属性、方法、事件、接口等等。并且可以直接创建对象,并调用对象的方法。反射像是一把钥匙,虽然看起来很小(只需要你获取到Type对象的引用),但是可以打开一个隐藏所有秘密的大门(可以访问到这个对象所有的信息)。反射主要会用到两个类,1是System.Type类,通过这个类可以访问任何给定的数据类型的信息。2是System.Reflection.Assembly类,它可以用于访问给定的程序集的信息。这里我们主要是说明System.Type类。
最简单的Type类的使用主要涉及到两个操作:
1.获取Type对象的引用
2.调用类型的方法
获取Type对象引用的3种常用方式:
A.typeof 运算符。例:Type type=typeof(int);
B.对象的GetType方法。例:int i=1;Type type=i.GetType();
C.Type类的静态方法GetType()。例:Type t=Type.GetType("System.String");
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()方法。
例子:这里结合反射和泛型的使用,给出一个可以实现类型转换的泛型方法,主要是将string类型转换成值类型。
public static T Convert<T>(string s)
{
Type type=typeof(T);
MethodInfo TryParse = type.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,
new Type[] { typeof(string), type.MakeByRefType() },
new ParameterModifier[] { new ParameterModifier(2) });
object[] parameters=new object[]{s,Activator.CreateInstance(type)};
bool success = (bool)TryParse.Invoke(null, parameters);
if (success)
{
return (T)parameters[1];
}
else
return default(T);
}
说明:类型的TryParse已经在另一篇文章中提过,Type中的GetMethod方法,该方法有多个重载,(MSDN:http://msdn.microsoft.com/en-us/library/system.type.getmethod.aspx),一般参数有两个,一个是方法名称字符串,另一个是搜索方法的条件枚举。搜索条件枚举要包含BindingFlags.Public,否则会返回NULL,如果是静态方法,要设置BindingFlag.static.得到MehtodInfo实例后,发射执行该方法:method.Invoke(obj,arrparam),obj是调用该方法所属的实例,如果调用的是静态方法,可以设置为NULL,arrparam 为方法参数数组。
控制台调用:
int i = TypeConvert.Convert<int>("123");
i++;
Console.WriteLine("{0}", i);
DateTime dt = TypeConvert.Convert<DateTime>("2009-01-31");
Console.WriteLine("{0}", dt);
结果: