前言
第一次写技术博客,由于自己也是正在学习C#,没有什么经验,只是遇到了这个问题,查看了别人的讲解自己根据自己的理解总结了一点内容。写得不好的或错的内容望大家多多指教,谢谢。
摘要
现在有这么几个问号:什么是委托?委托长啥样(怎样使用)?啥时候用委托?把这些问号变成一个个句号就是博客内容。好了,废话不多说,让我们一起进入主题吧!Let‘s Go
主体
什么是委托?
在msdn上是这样解释的:委托是可保存对方法的引用的类,是具有签名的类。只能对与其签名匹配的方法进行引用,等效于一个类型安全函数的指针或一个回调。看了解释大家是不是又有疑问了:什么是所谓的签名呢?其实所谓签名,就是自己签自己的名,名字就是用来区分的嘛,既然委托是对方法的引用,那么区分方法的条件就应该是区分委托的条件,委托的“签名”就应该是函数返回值和形参。有没有一点点明白了?
委托长啥样?
上面讲到了委托是一个类,那么使用委托就必须要实例化。首先声明一个委托类型:
delegate void myDelegate(string text);
其中,delegate为关键字,myDelegate 自定义的委托类型名,void和string text为委托的签名。
再声明一个这个委托类的委托:
myDelegate Update;
其中,myDelegate 为前面声明的委托类型,Update 为自定义的委托名。
最后,实例化委托有两种方式:
第一种:和一般实例化类一样。
Update = new myDelegate(UpdateUI);
其中,UpdateUI 为与委托一样的签名的函数,即 void UpdateUI(string)。
第二种:注册方法
Update +=UpdateUI;
当前面的一切准备工作完成之后,就可以放心使用委托了。使用委托传递参数:
Update(str);
其中,str 为string 型的变量。
该在什么时候使用?
不知道大家在使用多线程编程的时候有没有遇到过这样的报错:
这种情况就好比别人正忙着干自己的事,你突然去问他要个东西,你打断了别人别人会乐意么。那你提前给他讲你会来那这个东西,先委托他一下,那结果肯定会不一样。所以,编程跟做人是一样的。当一个线程正在使用某各变量的时候,另一个线程是无法访问到的。这是我们就需要委托该线程把我需要的内容通知给另一个需要使用的线程。
除此之外,大家应该都知道观察者模式吧。不知道也没关系,我可以把我知道的讲一下。举个例子,举什么呢,就举我在另外一篇博客上看到的例子吧,真的很贴切。假设有一个热水壶,当其温度达到90度以后警报就要响起,温度值也要显示在显示屏上等等,还可以有多种反应。那假设这一切的操作都是人来操作的话,那么人就是一个观察者,热水壶就是被观察者,当人看到温度变为了90度后,就要操作警报,显示温度等等,忙得不亦乐乎,而且还要动作快才能完成的好。作为程序员的你是不是很想为他减轻负担啊。
根据这个模型,聪明的你一定想到了方法。是这样的么?先建一个抽象的观察者类作为接口,然后添加到热水壶heater类中,当温度达到90度之后,再通过观察者广播出来。这样的实现方法其实就是观察者模式,你能想到说明你已经完全学会了观察者设计模式的使用。
其实在C#中,已经有了现成的可以充当观察者的类了,不用再自己新建,麻烦。聪明的你肯定又猜到了,这个类肯定是委托delegate类。对的,是它,是它,就是它。
class Heater { public delegate void myDelegate(int tempreture);//声明委托 public event myDelegate Message;//声明事件 public int tempreture; public void boild() { for(int i;i<101;i++) { this.tempreture=i; if(tempreture>90)
{
if(Message!=0)//如果有注册对象才可以使用
{
Message(tempreture);//调用所注册的方法 }
}
} } }
class Alarm
{
public void alarm(int tempreture)
{
Console.WriteLine("嘀嘀嘀,水温为{0}度了。",tempreture);
}
}
class Program {
static void Main()
{
Heater heater = new Heater();
Alarm alarm = new Alarm();
heater.Message+=alarm.alarm;//注册方法
heater.Message+=(new Alarm()).alarm;//给匿名对象注册方法
heater.boild();
}
}
总结
我的理解是: 在封装类时,想把在一个类中产生的数据传到另一个类使用,或者在一个线程中产生,同时又想在另一个线程中使用时就可以使用委托。大家如果还没有弄懂可以点击下面的链接继续学习,我也是看了这位大神的博文才有所收获:
http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html