在上一个建议中,我们使用委托实现了一个具有通知功能的文件传输类。可以像下面这样来使用这个文件传输类:
class Program
{
static void Main(string[]args)
{
FileUploader fl=new FileUploader();
fl.FileUploaded=Progress;
fl.FileUPloaded+=ProgressAnother;
fl.Upload();
}
static void Progress(int progress)
{
Console.WriteLine(progress);
}
static void ProgressAnother(int progress)
{
Console.WriteLine(string.Format("另一个通知方法:{0}",progress));
}
}
以上调用者代码本身是和FileUploader类一起的,这起码存在两个问题:
1)如果在Main中另起一个工作线程,该工作线程则可以将FileProgress委托链置为空:
fl.FileUploaded=null;
这会直接导致主线程不能再接收到FileUploader对象的通知。
2)可以在外部直接调用FileUploaded,如:
fl.FileUploaded(10);
这是不允许的。因为什么时候通知调用者,应该是FileUploader类自己的职责,而不是由调用者本身来决定。event关键字正是在这种情况下被提出来的,它为委托加了保护。例如,将FileUploader类的如下语句加上event,即将:
public FileUploadedHandler FileUploaded;
改为:
public event FileUploadedHandler FileUploaded;
这样,上面提到的几种情况在编译期间就会被阻止:
fl.FileUploaded=null;
fl.FileUploaded=Progress;
fl.FileUploaded(10);
以上代码编译会出现错误警告:
事件"ConsoleApplication1.FileUploader.FileUploaded"只能出现在+=或-=的左边(从类型"ConsoleApplication1.FileUploader"中使用时除外)