知道C#的“委托”名词很久了,一直都没有需求去了解它,最近因为要写的系统以及nbpm萌生了了解它的想法。
初步看了一下委托,第一感觉委托本质上就是C/C++中的函数指针。不同的是委托是面向对象,其构造更复杂和灵活,但掌握了之后使用更方便。同时函数指针只能是静态方法,而委托可以是静态方法,也可以是实例方法。
委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。
一、基本用法:
委托最基本的概念和方法使用下面的例子应该很明了:
1
using System;
2
namespace 委托
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用来传递事件的细节。
下面是两个例子:
例程二:
1
using System;
2
namespace 最简单的自定义事件
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
}
例程三:
1
using System;
2
namespace 带事件数据的事件
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
}
四、什么时候用委托:
- 当封装静态方法可取时。
- 当使用事件设计模式时。
- 当调用主不需要访问实现该方法的对象中的其他属性、方法或接口时
- 需要方便的组合时。
- 当类可能需要该方法的多个实现时。