1 什么是反射
反射就是对加载到公共语言运行时代码进行解析,并可以动态的访问或修改其中的一些IL。
可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
典型的用法就是抽象工厂方法,通过对配置文件指定程序集或命名空间的规范,然后在程序中对指定的程序集进行访问并构建想要的对象。
2 如何使用反射
要想能熟练的使用反射,必须对System.Reflection有一定的了解,在这个程序集下提供了诸如Assembly,MethodInfo,EventInfo等对加载的程序进行解析的一些列方法,而且需要对MSIL的构成方式有一定的了解。使用反射,无非是可以动态的对已经加载或可以访问的程序进行需要的操作。
3 示例
///
用于绑定的测试对象
namespace Simple_Type
{
public class MySimpleClass
{
public void MyMethod( string str, int i)
{
Console.WriteLine( " MyMethod parameters: {0}, {1} " , str, i);
}
public void MyMethod( string str, int i, int j)
{
Console.WriteLine( " MyMethod parameters: {0}, {1}, {2} " , str, i, j);
}
}
}
// 运行程序的主体
namespace Custom_Binder
{
using System;
using System.Reflection;
using System.Globalization;
using Simple_Type;
class MyMainClass
{
static void Main()
{
// 获取MySimpleClass类型
Type myType = typeof (MySimpleClass);
// 创建一个MySimpleClass 测试实例
MySimpleClass myInstance = new MySimpleClass();
// 创建了一个继承与System.Reflection.Binder的对象,该对象实现了Binder的抽象方法,
// 用于指定如何匹配实参与形参
MyCustomBinder myCustomBinder = new MyCustomBinder();
// 使用指定的搜索方式获取测试对象的MyMethord方法,并使用构建的myCustomBinder来匹配参数
MethodInfo myMethod = myType.GetMethod( " MyMethod " ,
BindingFlags.Public | BindingFlags.Instance,
myCustomBinder, new Type[] { typeof ( string ),
typeof ( int )}, null );
Console.WriteLine(myMethod.ToString());
// 调用按照前面的条件搜索到的方法
myType.InvokeMember( " MyMethod " , BindingFlags.InvokeMethod,
myCustomBinder, myInstance,
new Object[] { " Testing " , ( int ) 32 });
// 以下为自加的动态执行反射方法,与前面最明显的差异就在于创建测试对象的实例的方法不同
// 也没有使用指定的方式去搜索匹配的方法,注意,在这样的情况下,如果存在函数重载,
// 而继续使用InvokeMember的方法,并且没有指定Binder对象的时候,可能会产生异常
Object[] args;
args = new Object[] { " str " , 100 };
object obj = Assembly.GetEntryAssembly().CreateInstance( " Simple_Type.MySimpleClass " );
MethodInfo me = myType.GetMethod( " MyMethod " , new Type[] { typeof ( string ), typeof ( int ) });
me.Invoke(obj, args);
Console.ReadKey();
}
}
}
// 下面是继承System.Reflection.Binder 的部分代码,其具体的参数以及用法可以参考MSDN
class MyCustomBinder : Binder
{
public override MethodBase BindToMethod(
BindingFlags bindingAttr,
MethodBase[] match,
ref object [] args,
ParameterModifier[] modifiers,
CultureInfo culture,
string [] names,
out object state)
{
if (match == null )
throw new ArgumentNullException( " match " );
// Arguments are not being reordered.
state = null ;
// Find a parameter match and return the first method with
// parameters that match the request.
foreach (MethodBase mb in match)
{
ParameterInfo[] parameters = mb.GetParameters();
if (ParametersMatch(parameters, args))
return mb;
}
return null ;
}
}
namespace Simple_Type
{
public class MySimpleClass
{
public void MyMethod( string str, int i)
{
Console.WriteLine( " MyMethod parameters: {0}, {1} " , str, i);
}
public void MyMethod( string str, int i, int j)
{
Console.WriteLine( " MyMethod parameters: {0}, {1}, {2} " , str, i, j);
}
}
}
// 运行程序的主体
namespace Custom_Binder
{
using System;
using System.Reflection;
using System.Globalization;
using Simple_Type;
class MyMainClass
{
static void Main()
{
// 获取MySimpleClass类型
Type myType = typeof (MySimpleClass);
// 创建一个MySimpleClass 测试实例
MySimpleClass myInstance = new MySimpleClass();
// 创建了一个继承与System.Reflection.Binder的对象,该对象实现了Binder的抽象方法,
// 用于指定如何匹配实参与形参
MyCustomBinder myCustomBinder = new MyCustomBinder();
// 使用指定的搜索方式获取测试对象的MyMethord方法,并使用构建的myCustomBinder来匹配参数
MethodInfo myMethod = myType.GetMethod( " MyMethod " ,
BindingFlags.Public | BindingFlags.Instance,
myCustomBinder, new Type[] { typeof ( string ),
typeof ( int )}, null );
Console.WriteLine(myMethod.ToString());
// 调用按照前面的条件搜索到的方法
myType.InvokeMember( " MyMethod " , BindingFlags.InvokeMethod,
myCustomBinder, myInstance,
new Object[] { " Testing " , ( int ) 32 });
// 以下为自加的动态执行反射方法,与前面最明显的差异就在于创建测试对象的实例的方法不同
// 也没有使用指定的方式去搜索匹配的方法,注意,在这样的情况下,如果存在函数重载,
// 而继续使用InvokeMember的方法,并且没有指定Binder对象的时候,可能会产生异常
Object[] args;
args = new Object[] { " str " , 100 };
object obj = Assembly.GetEntryAssembly().CreateInstance( " Simple_Type.MySimpleClass " );
MethodInfo me = myType.GetMethod( " MyMethod " , new Type[] { typeof ( string ), typeof ( int ) });
me.Invoke(obj, args);
Console.ReadKey();
}
}
}
// 下面是继承System.Reflection.Binder 的部分代码,其具体的参数以及用法可以参考MSDN
class MyCustomBinder : Binder
{
public override MethodBase BindToMethod(
BindingFlags bindingAttr,
MethodBase[] match,
ref object [] args,
ParameterModifier[] modifiers,
CultureInfo culture,
string [] names,
out object state)
{
if (match == null )
throw new ArgumentNullException( " match " );
// Arguments are not being reordered.
state = null ;
// Find a parameter match and return the first method with
// parameters that match the request.
foreach (MethodBase mb in match)
{
ParameterInfo[] parameters = mb.GetParameters();
if (ParametersMatch(parameters, args))
return mb;
}
return null ;
}
}