ceny

博客园 首页 新随笔 联系 订阅 管理
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;
        }
}



-----------------------------------
4 小结
如上所述,使用反射的前提一般是对程序的逻辑构造有一定的了解,并知道如何使用特定的方式让程序执行自己需要的操作。

posted on 2008-05-27 09:55  笑西西  阅读(290)  评论(0)    收藏  举报