ceny

博客园 首页 新随笔 联系 订阅 管理
1 说明
前面的一个(使用简单的方法调用)只是展示了如何简单的调用一个方法,其实过程抽象一下就会发现如同自己在代码中调用指定的方法类似:创建对象---赋予指定的参数(个数和类型)---指定方法名(也算是调用),只是过程没有那么简单而已。
下面我们来介绍稍微复杂点的反射,就是将委托与事件挂钩来使用反射,注意,我们创建的示例是没有预先创建事件的。

2 示例
// 这个窗体是用来做测试的
class ExampleForm : Form 
{
    
public ExampleForm() : base()
    {
        
this.Text = "Click me";
    }
}

class Example
{
    
public static void Main()
    {
        Example ex 
= new Example();
        ex.HookUpDelegate();
    }


    
private void HookUpDelegate()
    {
       
// 使用 GetExecutingAssembly 方法来加载当前程序集。        
        Assembly assem = Assembly.GetExecutingAssembly();

      
// 获取表示类型的 Type 对象,并创建一个该类型的实例。由于窗体具有默认构造函数,
        
// 所以在下面的代码中使用了 CreateInstance 方法。如果您创建的类型没有默认构造函数,
        
// CreateInstance 方法还有其他几种重载可供使用。
        Type tExForm = assem.GetType("ExampleForm");
        Object exFormAsObj 
= Activator.CreateInstance(tExForm);

        
// 获取表示该事件的 EventInfo 对象,并使用 EventHandlerType 属性来获取用于处理事件的委托类型。
        EventInfo evClick = tExForm.GetEvent("Click");
        Type tDelegate 
= evClick.EventHandlerType;

        
// 获取表示处理事件的方法的 MethodInfo 对象。
        MethodInfo miHandler =
            
typeof(Example).GetMethod("LuckyHandler",
                BindingFlags.NonPublic 
| BindingFlags.Instance);

        
// 使用 CreateDelegate 方法创建委托的实例。
        Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler);


        
// 下面的代码获取 Click 事件的 add 访问器并以后期绑定方式调用它,并在委托实例中传递。参数必须作为数组传
        
// 递。
        MethodInfo addHandler = evClick.GetAddMethod();
        Object[] addHandlerArgs 
= { d };
        addHandler.Invoke(exFormAsObj, addHandlerArgs);
        Application.Run((Form)exFormAsObj);
    }

    
// 用来测试的委托事件
     private void LuckyHandler(Object sender, EventArgs e)
    {
        MessageBox.Show(
"This event handler just happened to be lying around.");
    }
}

上面的代码使用了一段通用的方法,获取对象->创建实例->获取对象信息(事件,委托)->将方法与事件绑定->运行
整段代码与自动添加事件的步骤有些类似,但是使用的方法全部都是程序在后续步骤中完成的,在此也可以显示出.net强大的功能。 1 说明
前面的一个(使用简单的方法调用)只是展示了如何简单的调用一个方法,其实过程抽象一下就会发现如同自己在代码中调用指定的方法类似:创建对象---赋予指定的参数(个数和类型)---指定方法名(也算是调用),只是过程没有那么简单而已。
下面我们来介绍稍微复杂点的反射,就是将委托与事件挂钩来使用反射,注意,我们创建的示例是没有预先创建事件的。

2 示例
// 这个窗体是用来做测试的
class ExampleForm : Form 
{
    
public ExampleForm() : base()
    {
        
this.Text = "Click me";
    }
}

class Example
{
    
public static void Main()
    {
        Example ex 
= new Example();
        ex.HookUpDelegate();
    }


    
private void HookUpDelegate()
    {
       
// 使用 GetExecutingAssembly 方法来加载当前程序集。        
        Assembly assem = Assembly.GetExecutingAssembly();

      
// 获取表示类型的 Type 对象,并创建一个该类型的实例。由于窗体具有默认构造函数,
        
// 所以在下面的代码中使用了 CreateInstance 方法。如果您创建的类型没有默认构造函数,
        
// CreateInstance 方法还有其他几种重载可供使用。
        Type tExForm = assem.GetType("ExampleForm");
        Object exFormAsObj 
= Activator.CreateInstance(tExForm);

        
// 获取表示该事件的 EventInfo 对象,并使用 EventHandlerType 属性来获取用于处理事件的委托类型。
        EventInfo evClick = tExForm.GetEvent("Click");
        Type tDelegate 
= evClick.EventHandlerType;

        
// 获取表示处理事件的方法的 MethodInfo 对象。
        MethodInfo miHandler =
            
typeof(Example).GetMethod("LuckyHandler",
                BindingFlags.NonPublic 
| BindingFlags.Instance);

        
// 使用 CreateDelegate 方法创建委托的实例。
        Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler);


        
// 下面的代码获取 Click 事件的 add 访问器并以后期绑定方式调用它,并在委托实例中传递。参数必须作为数组传
        
// 递。
        MethodInfo addHandler = evClick.GetAddMethod();
        Object[] addHandlerArgs 
= { d };
        addHandler.Invoke(exFormAsObj, addHandlerArgs);
        Application.Run((Form)exFormAsObj);
    }

    
// 用来测试的委托事件
     private void LuckyHandler(Object sender, EventArgs e)
    {
        MessageBox.Show(
"This event handler just happened to be lying around.");
    }
}

上面的代码使用了一段通用的方法,获取对象->创建实例->获取对象信息(事件,委托)->将方法与事件绑定->运行
整段代码与自动添加事件的步骤有些类似,但是使用的方法全部都是程序在后续步骤中完成的,在此也可以显示出.net强大的功能。
posted on 2008-05-29 09:05  笑西西  阅读(1335)  评论(0)    收藏  举报