定义
委托,就是将方法当做参数,传递给另外一个方法处理。
你可以把委托当做一种数据类型,而这种数据类型定义的是方法。
详解
委托,在现实中。就是,当你需要完成一件事情,但是你又不知道具体是如何完成的,所以委托给专业的人去办理,在此过程中,你只需要约定一份委托然后交由专业人士即可,你并不知道或者不了解中间的处理流程,而你需要的只是委托。
程序中也是一样,将本类无法完成的事情,交由第三方去解决。与现实不同的是,没有中间商赚差价!
举例
我们用发送消息来举例子。首先定义一个委托
public delegate void SendMessage(string msg);
这里使用了关键字delegate来定义了一个无返回值(void)的方法SendMessage(消息发送),参数包含一个string类型的msg
委托的定义和接口中定义方法很像,但是他们的概念不同。接口只是在定义规范,继承接口的类需要符合他的规范。但是委托的目的则是为了让符合其委托定义结构的方法做为参数去传递。
我们分别使用不同的平台来模拟发送消息(微信、短信)
public delegate void SendMessage(string msg);
//微信发送消息方法
public static void WXSendMessage(string msg)
{
Console.WriteLine("我是微信,我发送的消息是:" + msg);
}
//短信发送消息方法
public static void NoteSendMessage(string msg)
{
Console.WriteLine("我是短信,我发送的消息是:" + msg);
}
static void Main(string[] args)
{
SendMessage sm = new SendMessage(WXSendMessage);
sm("Hello");
Console.ReadKey();
}
注意,上面的例子,分别定义了WXSendMessage(string msg)和NoteSendMessage(string msg)两个方法,分别代表微信和短信。
然后再Main函数中,实例化了定义的委托SendMessage,同时直接将WxSendMessage(方法名称)作为参数传递给了委托。
注意:委托在使用时,必须实例化,所以需要先new一个委托。
然后使用委托实例化的对象sm直接括号参数列表,传入了一个"Hello".最终运行结果:
(1)上述例子还可以这么调用,运行效果是一样的。
new SendMessage(WXSendMessage)("Hello");
这种写法其实属于链式编程,即实例化对象以后会返回这个对象,同时直接调用这个对象。
(2)还可以这么调用,因为委托在定义时就是为了传递方法,那么直接将方法赋值给定义的委托,起到的效果是一样的。
SendMessage sm1 = WXSendMessage;
sm1("hellp");
多路广播
委托有个功能叫做多路广播,也叫做合并委托。
通过运算符"+"号将两个相同结构的委托合并起来,通过一次传递参数,实现两次调用。如:
static void Main(string[] args)
{
SendMessage sm = new SendMessage(WXSendMessage);
SendMessage sm1 = new SendMessage(NoteSendMessage);
sm = sm + sm1;
sm("Hello");
Console.ReadLine();
}
分别实例化了sm和sm1,一个是WXSendMessage一个是NoteSendMessage。然后通过加号运算符,将其关联在一起。
最后通过实例对象sm传递一次参数。
最终输出:
与之相反的,同样也支持"-"号操作
static void Main(string[] args)
{
SendMessage sm = new SendMessage(WXSendMessage);
SendMessage sm1 = new SendMessage(NoteSendMessage);
sm = sm + sm1;
sm = sm - sm1;
sm("Hello");
Console.ReadLine();
}
上述例子只会输出WXSendMessage方法对应的语句块。
因为sm1在广播队列中,通过运算符"-"号移除了。
总结
本文的例子看起来比较普通,仔细想想,你会感觉这样东西和直接的方法调用有什么不同?直接定义方法并且调用不就好了?为什么要使用委托来调用第三方呢?
首先是因为教学模式,举例简单便于你去理解委托是如何玩的。其次,面向对象编程语言,其很多特点都是模拟现实围绕对象模式去展开,所以委托的存在是不可少的。当业务中遇到这种需要交由不同个体去实现一个结构相同的事务时,最普通的做法就是利用if-else去区分逻辑,但是当这样的逻辑分支足够多时,难道还是用多个if-else去拼接吗?
从前书信很慢,车马很远,一生只。。。。。走错片场了,不好意思!
以前只有书信,其后有了短信,然后有了网络通讯,QQ,微信。现在五花八门的通讯方式越来越多。而我们如果使用if-else这样的分支逻辑显然会加大代码的冗余和判断的繁琐。不如使用委托,将所有的模块拆分开来,按照固定的结构去委托调用,这样各自就只需要专注自己的实现即可。
而委托的广播功能就更好理解了。
比如你发一个微信朋友圈,可以同步发送到QQ空间。这是不是和委托的广播效果一样?