我看委托

      知道C#的“委托”名词很久了,一直都没有需求去了解它,最近因为要写的系统以及nbpm萌生了了解它的想法。
      初步看了一下委托,第一感觉委托本质上就是C/C++中的函数指针。不同的是委托是面向对象,其构造更复杂和灵活,但掌握了之后使用更方便。同时函数指针只能是静态方法,而委托可以是静态方法,也可以是实例方法。
      委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。
一、基本用法:
      委托最基本的概念和方法使用下面的例子应该很明了:

 1using System;
 2namespace 委托
 3{
 4  delegate int NumOpe(int a,int b); //委托声明
 5  class Class1
 6  {
 7    static void Main(string[] args)
 8    {
 9      Class1 c1 = new Class1();
10      NumOpe p1 = new NumOpe(c1.Add); //委托实例化
11      Console.WriteLine(p1(1,2)); //委托调用
12      Console.ReadLine();
13    }

14    private int Add(int num1,int num2)
15    {
16      return(num1+num2);
17    }

18  }

19}

      例中,委托NumOpe引用了方法Add。
      委托声明了以后,就可以象类一样进行实例化,实例化时把要引用的方法(如:Add)做为参数,这样委托和方法就关联了起来,就可以用委托来引用方法了。
      委托和所引用的方法必须保持一致:
      1、参数个数、类型、顺序必须完全一致。
      2、返回值必须一致。
二、委托的应用-事件
      委托的一个最常用的应用就是事件。
      事件和处理方法之间是怎么联系起来的呢?委托就是他们中间的桥梁,事件发生时,委托会知道,然后将事件传递给处理方法,处理方法进行相应处理。
      比如在WinForm中最常见的是按钮的Click事件,它是这样委托的:
      this.button1.Click += new System.EventHandler(this.button1_Click);
      按按钮后就会出发button1_Click方法进行处理。EventHandler就是系统类库里已经声明的一个委托。
三、自定义事件及其处理
      自定义事件是更委托的复杂的应用。
      EventHandler以及其它自定义的事件委托都是一类特殊的委托,他们有相同的形式:
      delegate void 事件委托名(object sender,EventArgs e);
      object用来传递事件的发生者,比如二中的Button控件就是一个事件发生者;EventArgs用来传递事件的细节。
      下面是两个例子:
      例程二:

 1using System;
 2namespace 最简单的自定义事件
 3{
 4  /// <summary>
 5  /// 事件发送类
 6  /// </summary>

 7  class Class1
 8  {
 9    public delegate void UserRequest(object sender,EventArgs e); //定义委托
10    public event UserRequest OnUserRequest; //定义一个委托类型的事件
11    public void run()
12    {
13      while(true)
14      {
15        if(Console.ReadLine()=="a")
16        {//事件监听
17          OnUserRequest(this,new EventArgs()); //产生事件
18        }

19      }

20    }

21  }

22  /// <summary>
23  /// 事件接收类
24  /// </summary>

25  class Class2
26  {
27    static void Main(string[] args)
28    {
29      Class1 c1 = new Class1();
30      c1.OnUserRequest += new Class1.UserRequest(c1_OnUserRequest); //委托实例化后绑定到事件
31      c1.run();
32    }

33    private static void c1_OnUserRequest(object sender, EventArgs e)
34    {//事件处理方法
35      Console.WriteLine("\t你触发了事件!");
36    }

37  }

38}

      例程三:

 1using System;
 2namespace 带事件数据的事件
 3{
 4  /// <summary>
 5  /// 带事件数据的事件类,从EventArgs继承
 6  /// </summary>

 7  class OnUserRequestEventArgs:EventArgs
 8  {
 9    private string inputText;
10    public string InputText
11    {
12      get
13      {
14        return inputText;
15      }

16      set
17      {
18        inputText = value;
19      }

20    }

21  }

22  /// <summary>
23  /// 事件发送类
24  /// </summary>

25  class Class1
26  {
27    public delegate void UserRequest(object sender,OnUserRequestEventArgs e);
28    public event UserRequest OnUserRequest;
29    public void run()
30    {
31      while(true)
32      {
33        Console.WriteLine("请输入内容:");
34        string a=Console.ReadLine();
35        //if(a=="a")
36        //{
37        OnUserRequestEventArgs e1 = new OnUserRequestEventArgs();
38        e1.InputText = a;
39        OnUserRequest(this,e1);
40        //}
41      }

42    }

43  }

44  /// <summary>
45  /// 事件接收类
46  /// </summary>

47  class Class2
48  {
49    [STAThread]
50    static void Main(string[] args)
51    {
52      Class1 c1 = new Class1();
53      c1.OnUserRequest += new Class1.UserRequest(c1_OnUserRequest);
54      c1.run();
55    }

56    private static void c1_OnUserRequest(object sender, OnUserRequestEventArgs e)
57    {
58      Console.WriteLine("\t你输入的是:"+e.InputText);
59    }

60  }

61}
四、什么时候用委托: 
  • 当封装静态方法可取时。
  • 当使用事件设计模式时。
  • 当调用主不需要访问实现该方法的对象中的其他属性、方法或接口时
  • 需要方便的组合时。
  • 当类可能需要该方法的多个实现时。
posted @ 2007-06-06 13:13  badwood  阅读(187)  评论(0编辑  收藏  举报
Badwood's Blog