委托与事件

来源:互联网 发布:linux svn上传新项目 编辑:程序博客网 时间:2024/05/01 11:27
 

1。 什么是委托?

     委托和事件这两个概念是完全配合的。委托仅仅是函数指针,那就是说,它能够引用函数,通过传递地址的机制完成。
     委托是一个类,当你对它实例化时,要提供一个引用函数,将其作为它构造函数的参数。

   每一个委托都有自己的签名,例如:Delegate int SomeDelegate(string s, bool b);是一个委托申明,在这里,提及的签名,
    就是说SomeDelegate 这个委托 有 string 和 bool 类型的形参,返回一个int 类型。

   上面提及的:当你对委托实例化时,要提供一个引用函数,将其作为它构造函数的参数。
    这里要注意了:被引用的这个函数必须和委托有相同的签名。

   看下面的函数:

   private int SomeFunction(string str, bool bln){...}

   你可以把这个函数传给SomeDelegate的构造函数,因为他们有相似的签名(in other words,他们都有相同的形参类型和个数,并且返回相同的数据类型)。

     SomeDelegate sd = new SomeDelegate(SomeFunction);

   sd 引用了 SomeFunction,也就是说,SomeFunction已被sd所登记注册,如果你调用 sd,SomeFunction 这个函数也会被调用,
   记住:我所说 SomeFunction的含义,后面,我们会用到它。

2.

  一、委托
委托类似于函数指针,但函数指针只能引用静态方法,而委托既能引用静态方法,也能引用实例方法。

委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。
例程一:

using System;

namespace 委托
{
   delegate int NumOpe(int a,int b); //委托声明
   class Class1
   {
     static void Main(string[] args)
     {
       Class1 c1 = new Class1();
       NumOpe p1 = new NumOpe(c1.Add); //委托实例化
       Console.WriteLine(p1(1,2)); //委托调用
       Console.ReadLine();
     }

     private int Add(int num1,int num2)
     {
       return(num1+num2);
     }
   }
}
例中,委托NumOpe引用了方法Add。
委托声明了以后,就可以象类一样进行实例化,实例化时把要引用的方法(如:Add)做为参数,这样委托和方法就关联了起来,就可以用委托来引用方法了。
委托和所引用的方法必须保持一致:
1、参数个数、类型、顺序必须完全一致。
2、返回值必须一致。

二、事件

事件有很多,比如说鼠标的事件:MouserMove,MouserDown等,键盘的事件:KeyUp,KeyDown,KeyPress。

有事件,就会有对事件进行处理的方法,而事件和处理方法之间是怎么联系起来的呢?委托就是他们中间的桥梁,事件发生时,委托会知道,然后将事件传递给处理方法,处理方法进行相应处理。

比如在WinForm中最常见的是按钮的Click事件,它是这样委托的:this.button1.Click += new System.EventHandler(this.button1_Click);按按钮后就会出发button1_Click方法进行处理。EventHandler就是系统类库里已经声明的一个委托。

三、自定义事件及其处理

EventHandler以及其它自定义的事件委托都是一类特殊的委托,他们有相同的形式:

delegate void 事件委托名(object sender,EventArgs e);

object用来传递事件的发生者,比如二中的Button控件就是一个事件发生者;EventArgs用来传递事件的细节。

例程二:
using System;

namespace 最简单的自定义事件
{
   /// <summary>
   /// 事件发送类
   /// </summary>
   class Class1
   {
     public delegate void UserRequest(object sender,EventArgs e); //定义委托
     public event UserRequest OnUserRequest; //定义一个委托类型的事件

     public void run()
     {
       while(true)
       {
         if(Console.ReadLine()=="a")
         {//事件监听
           OnUserRequest(this,new EventArgs()); //产生事件
         }
       }
     }
   }

   /// <summary>
   /// 事件接收类
   /// </summary>
   class Class2
   {
     static void Main(string[] args)
     {
       Class1 c1 = new Class1();
       c1.OnUserRequest += new Class1.UserRequest(c1_OnUserRequest); //委托实例化后绑定到事件
       c1.run();
     }

     private static void c1_OnUserRequest(object sender, EventArgs e)
     {//事件处理方法
       Console.WriteLine("/t你触发了事件!");
     }
   }
}
例程三:
using System;

namespace 带事件数据的事件
{
   /// <summary>
   /// 带事件数据的事件类,从EventArgs继承
   /// </summary>
   class OnUserRequestEventArgs:EventArgs
   {
     private string inputText;
     public string InputText
     {
       get
       {
         return inputText;
       }
       set
       {
         inputText = value;
       }
     }
   }

   /// <summary>
   /// 事件发送类
   /// </summary>
   class Class1
   {
     public delegate void UserRequest(object sender,OnUserRequestEventArgs e);
     public event UserRequest OnUserRequest;

     public void run()
     {
       while(true)
       {
         Console.WriteLine("请输入内容:");
         string a=Console.ReadLine();
         //if(a=="a")
         //{
         OnUserRequestEventArgs e1 = new OnUserRequestEventArgs();
         e1.InputText = a;
         OnUserRequest(this,e1);
         //}
       }
     }
   }

   /// <summary>
   /// 事件接收类
   /// </summary>
   class Class2
   {
     [STAThread]
     static void Main(string[] args)
     {
       Class1 c1 = new Class1();
       c1.OnUserRequest += new Class1.UserRequest(c1_OnUserRequest);
       c1.run();
     }

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

原创粉丝点击