上篇,我们讨论了委托最核心的原理——将方法作为方法的参数,这一篇我们聊聊委托还要哪些用法
我们继续用上次打招呼的例子来分析委托的其他用法,下边是上一篇的DEMO
namespace 委托DEMO
{
public delegate void GreetingDelegate(string name);
class Program
{
private static void GreetPeople(string name,GreetingDelegate MakeGreeting)
{
MakeGreeting(name);
}
private static void EnglishGreeting(string name)
{
Console.WriteLine("Morning," + name);
}
private static void ChineseGreeting(string name)
{
Console.WriteLine("你好," + name);
}
static void Main(string[] args)
{
GreetPeople("Celine", EnglishGreeting);
GreetPeople("陈丹", ChineseGreeting);
Console.ReadKey();
}
}
}
我们在客户端也可以先定义变量,然后将变量传入GreetPeople,代码如下:
static void Main(string[] args)
{
//GreetPeople("Celine", EnglishGreeting);
//GreetPeople("陈丹", ChineseGreeting);
//Console.ReadKey();
string name1, name2;
name1 = "Celine";
name2 = "陈丹";
GreetPeople(name1, EnglishGreeting);
GreetPeople(name2, ChineseGreeting);
Console.ReadKey();
}
既然委托GreetingDelegate和String是一样的,都是定义了一个参数类型,那么类比上边定义string变量的过程,我们是不是先可以先声明两个委托呢?
static void Main(string[] args)
{
//GreetPeople("Celine", EnglishGreeting);
//GreetPeople("陈丹", ChineseGreeting);
//Console.ReadKey();
//string name1, name2;
//name1 = "Celine";
//name2 = "陈丹";
GreetingDelegate delegate1, delegate2;
delegate1 = EnglishGreeting;
delegate2 = ChineseGreeting;
GreetPeople("Celine", delegate1);
GreetPeople("陈丹", delegate2);
Console.ReadKey();
}
我们得到了相同的结果,这样做是没有问题的。
但是委托不同于string的一个特性:可以将多个方法赋同一个委托,或者理解为将多个方法绑定到同一个委托,当调用这个委托的时候,将以此调用其绑定的方法
static void Main(string[] args)
static void Main(string[] args)
{
//声明一个委托的对象
GreetingDelegate delegate1;
//"="是赋值
delegate1 = EnglishGreeting;
// "+="是绑定
delegate1 += ChineseGreeting;
//先后调用两个不同的打招呼的方法
GreetPeople("Celine", delegate1);
Console.ReadKey();
}
<br>
//解绑
delegate1 -= EnglishGreeting;//取消对英语的绑定
总结:委托和接口对比
使用委托,可以隔离变化,同样接口或者抽象类也可以起到隔离变化的作用,其实委托的作用和只含有一个方法的接口的作用是一样的.
假设我们定义了一个打招呼的接口,定义一些具体的类(英语打招呼,中文打招呼,日语打招呼等等)去实现打招呼的接口,我们在客户端调用的时候相当于传进去的参数就是(string name,IGreeting makeGreeting),但是接口实现的代码量要比使用委托多很多。
所以说在不同的场景下,选择合适的方法去达到相同的效果,是设计师最终需要考量的