直接使用委托的写法,如下:
using System; namespace ConsoleAppTest { class Program { class Test { static void Main(string[] args) { FileUploader f1 = new FileUploader(); //委托设置为空 f1.FileUploaded = null; f1.FileUploaded = Progress; //重置委托 f1.FileUploaded = ProgressAnother; f1.Upload(); //外部直接调用 f1.FileUploaded(6); Console.Read(); } } class FileUploader { public delegate void FileUploadedHandler(int progress); public FileUploadedHandler FileUploaded; public void Upload() { int fileProgress = 5; while (fileProgress > 0) { //传输代码,省略 fileProgress--; if (FileUploaded != null) { FileUploaded(fileProgress); } } } } static void Progress(int progress) { Console.WriteLine(progress); } static void ProgressAnother(int progress) { Console.WriteLine("另一个方法:{0}", progress); } } }
以上调用者代码本身是和FileUploader类一起的,这起码存在两个问题:
1)如果在Main中另起一个线程,该工作线程则可以将FileProgress委托链置为空:
f1.FileUploaded = null;
2)可以在外部调用FileUploaded,如:
f1.FileUploaded(6) ;
这应该是不允许的,因为什么时候通知调用者,应该是FileUploader类自己的职责,而不是调用者本身来决定的。event关键字正是在这种情况下被提出来的,它为委托加了保护。
使用event的写法,如下:
添加event关键字后,上面提到的几种情况会被阻止。
添加event的调用写法
static void Main(string[] args) { FileUploader f1 = new FileUploader(); f1.FileUploaded += Progress; f1.Upload(); Console.Read(); }