C# delegate委托

委托: delegate

1.什么是委托
delegate(委托)是一种特殊的类,用来定义一群【具有共同特征】的方法;这些方法作用于相同类型和顺序的参数, 但不确定具体的执行方式;
对于每一个委托的实例,你可以将具体的方法挂载(+=)到委托实例上,使该委托实例获得具体的执行方式。

哈,我猜,你很可能完全听不懂前面我说了什么。事实上,绝大多数相关资料中对委托的解释,比我刚才说的还要晦涩难懂。

所以——来听我讲故事吧!

【将故事中的各段代码拼接起来,即可编译执行。】

2.讲故事时间到!

某村庄深受强盗(Robber)的困扰。村长在告示牌上张贴了悬赏委托Eliminate:想办法消除两名强盗Tom和Bob的威胁。
但村长没有对【委托:消除强盗威胁】的具体方法作出要求;如何对付强盗呢?这将由接下委托的勇士们自己考量。

1
2
3
4
5
6
7
8
9
10
11
12
namespace delegateShow
{
public class Robber
{
public string name;
public Robber(string str)
{
name = str;
}
}

public delegate void Eliminate(Robber robber);

有一位战士看到了委托。战士拥有Kill(Robber x)能力,可以杀死强盗;

战士不假思索地揭走了一张委托,将其作为自己的任务 eliminate。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Warrior
{
public Warrior()
{
Console.WriteLine("我是战士");
}

public void Kill(Robber x)
{
Console.WriteLine("我杀死了强盗" + x.name);
}

public Eliminate eliminate = null;//战士接下了委托,将其变成了自己的方法eliminate,具体执行方式尚未确定
}

有一位诗人也看到了委托。诗人拥有Persuade(Robber x)能力,可以劝服强盗;

诗人也觉得胸有成竹,于是也揭走一张委托,将其作为自己的任务eliminate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Poet
{
public Poet()
{
Console.WriteLine("我是诗人");
}

public void Persuade(Robber x)
{
Console.WriteLine("我劝服了强盗" + x.name);
}

public Eliminate eliminate = null;//诗人接下了委托,将其变成了自己的方法eliminate,具体执行方式尚未确定
}>

两名强盗Tom和Bob出现了。战士warrior和诗人poet各自出发,战士去处理强盗Tom,诗人去处理强盗Bob。

战士认为,执行委托Eliminate的方法应该是杀死强盗。

诗人认为,执行委托Eliminate的方法应该是劝服强盗。

于是,他们各自拿定了主意,并以自己的方式执行委托——

战士杀死了强盗Tom,诗人劝服了强盗Bob.

虽然战士和诗人执行委托的方式大不相同,但都符合村长所贴出委托的要求,因此他们都完成了任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    public class MainClass
{
static void Main(string[] args)
{
//两名强盗出现
Robber Tom = new Robber("Tom");
Robber Bob = new Robber("Bob");

//现在战士warrior和诗人poet出发了,战士去处理强盗Tom,诗人去处理强盗Bob

Warrior warrior = new Warrior();//战士登场
warrior.eliminate += warrior.Kill;
//战士对自己接下的委托实例eliminate进行了解释,使得这个委托的具体执行方式变成了战士的Kill方法——杀死强盗
warrior.eliminate(Tom);//战士对Tom执行了自己的委托实例eliminate


Poet poet = new Poet();//诗人登场
poet.eliminate += poet.Persuade;
//诗人对自己接下的委托实例eliminate进行了解释,使得这个委托的具体执行方式变成了诗人的Persuade方法——劝服强盗
poet.eliminate(Bob);//诗人对Bob执行了自己的委托实例eliminate


Console.ReadLine();
}
}
}

执行结果:


3.归纳总结

通过上面的大型示例,你现在是否已经初步了解了委托-delegate的作用呢?

委托是一个类,它通过描述一组【参数类型和顺序】,定义了方法的类型,从而使得:若干个不同的方法,只要具备相同的【参数类型和顺序】,就可以被归纳为同一类型,也就是"委托"。

(1)通过将方法声明为委托的实例(例如上文中的eliminate),我们可以将具体的方法赋值给该委托实例,从而动态地改变该委托实例所代表的具体方法内容,增加程序的灵活性;

(在示例中,战士和诗人按照各自的理解,对委托实例Eliminate eliminate作出了不同的执行方式,就是灵活性的体现)

(2)而通过将委托作为方法的形参,我们还可以将一个【符合委托所需参数格式】的方法当作【另一个方法的参数】来进行传递。这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

注意:出于绝对浅显易懂的需要,上面的内容牺牲了很多严谨性和全面性,并没有全面地介绍委托的性质和用法,你可以自行查阅其它资料来完善你学到的知识。

到这里,你有可能会觉得,委托的概念有点“花里胡哨”,实际的作用不是很明显;这样想其实是有道理的,因为我们还没有见识到委托的主要作用在何处。

其实,委托是C#中事件驱动机制的基础;【事件】才是委托最大的用武之处。

那么,事件驱动又是什么呢?我们下篇笔记再会~