一、委托委托类似于函数指针,但函数指针只能引用静态方法,而委托既能引用静态方法,也能引用实例方法。 委托使用分三步: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就是系统类库里已经声明的一个委托。 -------委托实例化,this.buttion1_click为方法名 三、自定义事件及其处理 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); } } } 例程三跟例程二唯一的差别在于自定义了一个类OnUserRequestEventArgs,从EventArgs继承 ------------------------------------------------------------------------------------------ using System; class TestClass { static void Main(string[] args) { EventClass myEventClass = new EventClass(); myEventClass.CustomEvent += new EventClass.CustomEventHandler(CustomEvent1); // 关联事件句柄; myEventClass.CustomEvent += new EventClass.CustomEventHandler(CustomEvent2); myEventClass.InvokeEvent(); myEventClass.CustomEvent -= new EventClass.CustomEventHandler(CustomEvent2); myEventClass.InvokeEvent(); myEventClass.Load += new EventClass.CustomEventHandler(Load1); myEventClass.onLoad(); }private static void CustomEvent1(object sender, EventArgs e) { Console.WriteLine("Fire Event 1"); }private static void CustomEvent2(object sender, EventArgs e) { Console.WriteLine("Fire Event 2"); } private static void Load1(object sender, EventArgs e) { Console.WriteLine("Current background color is {0}. Please input:", System.Console.BackgroundColor.ToString()); }}public class EventClass { public delegate void CustomEventHandler(object sender, EventArgs e);//首先定义一个委托类型的对象CustomEventHandler//用delegate数据类型声明事件,要用event关键字,这里定义了两个字件; public event CustomEventHandler CustomEvent; public event CustomEventHandler Load; public void InvokeEvent() { CustomEvent(this, EventArgs.Empty); } public void onLoad() { Console.BackgroundColor = ConsoleColor.Red; Load(this, EventArgs.Empty); string s = Console.ReadLine(); if (s != "yuping") { Console.WriteLine("You must type 'yuping' for change it !"); } else { Console.BackgroundColor = System.ConsoleColor.Black; Console.Clear(); }} }在包含事件声明的类中,声明一个数据类型是委托的这么样的一个对象CustomEventHandler, 它有两个参数(sender和e);在这里使用委托的目的就是在运行中向参数传递方法,并由委托对象生成的实例接收这个参数方法的返回值,因此,在声明委托型的对象时应根据类中的方法结构来定义,或者说在引用类中应当根据委托型对象的结构来生成响应事件的方法结构,比如两者都有哪些类型的参数、返回值的类型,也就是说两者要保持一致。同时,要正确地使用C#中的委托,就必须保持三个步骤:声明??实例化??调用。 在上面的代码中,EventClass 类就体现了这个原则: 1. 声明委托类型的对象: public delegate void CustomEventHandler(object sender, EventArgs e); 2. 创建CustomEventHandler对象的实例CustomEvent:public event CustomEventHandler CustomEvent; 3. 在InvokeEvent()方法中实现了对该事件的调用,引用事件。
-------------------------------------------------------------------------------- public delegate void RunHandler(string name); public class Man : IFlay, IRun { public event EventHandler Speak; public event RunHandler Sport; public void OnRun(string name) { if (Sport != null) { Sport(name); } } public void onSpeak() { if (Speak != null) { Speak(this, new EventArgs()); } } public string Flay(string name) { return name + ",飞!"; } public string Run(string name) { return name + ",跑!"; } }
public interface IRun { string Run(string name); }
public interface IFlay { string Flay(string name); }
//--------------------------调用: RunHandler rh = new RunHandler((string a) => { MessageBox.Show(a); }); rh("fx go zoo!"); ma.Speak += new EventHandler(ma_Speak); ma.onSpeak(); //ma.Sport += new RunHandler(ma_Sport); ma.Sport += delegate(string name) { MessageBox.Show(name); }; ma.OnRun("fx"); |