即然要说委托,我们就先来看一下委托的定义,“委托(delegate)是一种存储函数引用的类型”。定义的东西都很难理解,从字面来看(用破解英文的方式从后到前),首先它是一种类型,不知道是什么类型,我们暂时称它为特殊类型,其次它“存储了函数的引用”,好吧,理解的还不是很深刻,那我们就说它是一种存储了特殊类型的函数引用。OK,成功破解!
翻译为凡文就是,我是一个经纪人(我不姓宋),我手下有N个艺人(暂定两个),A艺人(影帝),B艺人(歌星),而我就是四处拉活的经纪人包工头C(委托),当我接到拍戏的时候,我就叫A艺人去执行,当接到中国好嗓子的时候我就叫B艺人去唱歌(我只是存储了函数引用的类型),我接到了什么类型的活,就叫谁去干,因为他们都委托了我(我就是个中介,为什么我自己不去干,因为我没这技能,而且我很忙)。
答1:“事件是多播委托,这个在C#基础知识书籍中都会提到,根本没必要问。声明为事件的好处是,可以在程序各个位置添加相互独立的事件处理函数,不用担心被其它人给覆盖掉。”
答2:“跨线程访问控件之类的都需要用到委托,子线程访问主线程的控件或者方法都得用到委托。”
答3:“变量不存在跨线程一说,只是UI对象要在非UI线程里操作,需要委托给UI线程去处理,而变量在任何线程你都可以随意访问,这时你要做好同步,或者使用线程安全的对象“
答案往往都很让人匪夷所思(假装很懂的样子),带着一个问题和三个答案,下面我们来说一段相声(看一下实例代码)。
委托的声明非常类似于函数,但不带函数体,且要使用关键字”delegate“。委托的声明指定了一个返回类型和一个参数列表。
首先是C#语法:public delegate void BrokerEventHandler(string sEvent);
delegate 是关键词,【注:EventHandler是一个声明委托的微软C#的命名标准,我的习惯是标准就要第一时间说,也就这个命名习惯要第一时间养成】
这就是委托,看看和我们一般的方法有什么区别呢?
public void Sing(string sEvent)
{
方法体
}
委托只是个命令,做事情是别人,而在程序世界里委托只是存储了各个方法的地址,而他自己也是什么也不做的。
public class TestDelegate{
public delegate void BrokerEventHandler(string sEvent); //我就是经纪人(委托),带上"delegate"这个狗牌,让大家知道我是接活的
BrokerEventHandler brokerEH; //存储函数引用
public void Sing(string sEvent) //这个就是歌星
{
Debug.Log ("EventHandler 唱歌去 :" + sEvent);
}
public void Performance(string sEvent) //这个就是传说中的影帝
{
Debug.Log ("EventHandler 拍戏去 :" + sEvent);
}
public static void Main(string[] args)
TaskManager ("Performance");
}
public void TaskManager(string sEvent) //我就是个传话的,命令都在我这里下发
{
if (sEvent == "Sing")
{
brokerEH = new BrokerEventHandler (Sing); //叫歌星唱歌
} else if (sEvent == "Performance")
{
brokerEH = new BrokerEventHandler (Performance); //叫影帝拍戏
}
brokerEH (sEvent);
}
}
BrokerEventHandler brokerEH = new BrokerEventHandler (Sing);
这是委托的声明方法, BrokerEventHandler (委托的方法);委托的方法必须要加上,因为委托的构造函数是不为空的。
注:委托的参数和返回类型,都要和你要具体委托的方法要一致,例:
public delegate void BrokerEventHandler(string sEvent);public void Sing(string sEvent)
{
Debug.Log ("EventHandler 唱歌去 :" + sEvent);
}
上面的委托只是每次派一个任务给一个人,如果一要一起派两个人去干活呢,用程序的第一思维那就”+=“呗。没错,这就是”委托链”。
brokerEH = new BrokerEventHandler (Sing);
brokerEH += Performance;
代码:
public static void Main(string[] args)
TaskManager ("SingAndPerformance");
}
public void TaskManager(string sEvent)
{
if (sEvent == "Sing") {
brokerEH = new BrokerEventHandler (Sing);
} else if (sEvent == "Performance") {
brokerEH = new BrokerEventHandler (Performance);
} else {
brokerEH = new BrokerEventHandler (Sing);
brokerEH += Performance;
}
brokerEH (sEvent);
}
这样就可以先唱歌,再拍戏。
实际上,这里可以使用简单的语法:
brokerEH = new BrokerEventHandler (Sing); 简写为:brokerEH =Sing;
意思是一样的,写全的只是看着清晰一些,然并卵,看个人喜好了。