1 什么是反射
反射就是对加载到公共语言运行时代码进行解析,并可以动态的访问或修改其中的一些IL。
可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
典型的用法就是抽象工厂方法,通过对配置文件指定程序集或命名空间的规范,然后在程序中对指定的程序集进行访问并构建想要的对象。
2 如何使用反射
要想能熟练的使用反射,必须对System.Reflection有一定的了解,在这个程序集下提供了诸如Assembly,MethodInfo,EventInfo等对加载的程序进行解析的一些列方法,而且需要对MSIL的构成方式有一定的了解。使用反射,无非是可以动态的对已经加载或可以访问的程序进行需要的操作。
3 示例
反射就是对加载到公共语言运行时代码进行解析,并可以动态的访问或修改其中的一些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;
}
}
-----------------------------------
4 小结
如上所述,使用反射的前提一般是对程序的逻辑构造有一定的了解,并知道如何使用特定的方式让程序执行自己需要的操作。
浙公网安备 33010602011771号