我看委托
知道C#的“委托”名词很久了,一直都没有需求去了解它,最近因为要写的系统以及nbpm萌生了了解它的想法。
初步看了一下委托,第一感觉委托本质上就是C/C++中的函数指针。不同的是委托是面向对象,其构造更复杂和灵活,但掌握了之后使用更方便。同时函数指针只能是静态方法,而委托可以是静态方法,也可以是实例方法。
委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。
一、基本用法:
委托最基本的概念和方法使用下面的例子应该很明了:
using System;2
namespace 委托3
{4
delegate int NumOpe(int a,int b); //委托声明5
class Class16
{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用来传递事件的细节。
下面是两个例子:
例程二:
using System;2
namespace 最简单的自定义事件3
{4
/// <summary>5
/// 事件发送类6
/// </summary>7
class Class18
{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 Class226
{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
}例程三:
using System;2
namespace 带事件数据的事件3
{4
/// <summary>5
/// 带事件数据的事件类,从EventArgs继承6
/// </summary>7
class OnUserRequestEventArgs:EventArgs8
{9
private string inputText;10
public string InputText11
{12
get13
{14
return inputText;15
}16
set17
{18
inputText = value;19
}20
}21
}22
/// <summary>23
/// 事件发送类24
/// </summary>25
class Class126
{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 Class248
{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
}- 当封装静态方法可取时。
- 当使用事件设计模式时。
- 当调用主不需要访问实现该方法的对象中的其他属性、方法或接口时
- 需要方便的组合时。
- 当类可能需要该方法的多个实现时。


浙公网安备 33010602011771号