反射 --- 实现简单的方法调用

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 ;
        }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值