在C#中,委托和事件是比较容易混淆的两个知识点,本篇博客就记录一下委托和事件之间的区别。
定义上的区别
委托:委托实际上是一个类,用来表示一个函数,可以理解为C++中的函数指针。
事件:事件是一个修饰符,用来修饰一个委托类型的属性,表示该委托的部分功能被限制了。
我们可以这么理解:委托是类,定义了委托后,就可以像使用类一样的来使用这个委托,而事件修饰了委托后则是表示限制这个委托的部分功能,使其满足作为事件的规则。
那么事件究竟限制了委托的什么功能呢?主要是下面的这两个限制:
调用的限制
委托的调用没有限制,可以在任意的地方进行调用,而事件修饰过的委托只能在定义自己的类中进行调用(注意连子类都不允许调用),如下:
1 using System; 2 3 namespace Study 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 new App(); 10 11 Console.Read(); 12 } 13 } 14 15 public delegate void Foo(); 16 17 public class Test 18 { 19 public Foo foo1; 20 21 public event Foo foo2; 22 23 public Test() 24 { 25 foo1 += Func; 26 foo1(); 27 28 foo2 += Func; 29 foo2(); 30 } 31 32 public void Func() 33 { 34 Console.WriteLine("Test Func"); 35 } 36 } 37 38 public class App 39 { 40 public App() 41 { 42 Test test = new Test(); 43 44 test.foo1(); 45 46 test.foo2();//这个会报错 47 } 48 } 49 }
注册的限制
委托可以使用“=”、“+=”、“-=”三种符号来表示赋值,添加和移除一个函数,而事件修饰过的委托在自己的类中也可以使用这三个符号(注意子类也属于外部的类),而在外部的类中时则只能使用“+=”和“-=”来添加移除函数,不能使用“=”进行赋值,下面我们来看一个具体的例子:
1 using System; 2 3 namespace Study 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 new App(); 10 11 Console.Read(); 12 } 13 } 14 15 public delegate void Foo(); 16 17 public class Test 18 { 19 public Foo foo1; 20 21 public event Foo foo2; 22 23 public Test() 24 { 25 foo1 = Func; 26 foo1 += Func; 27 foo1(); 28 29 foo2 = Func; 30 foo2 += Func; 31 foo2(); 32 } 33 34 public void Func() 35 { 36 Console.WriteLine("Test Func"); 37 } 38 } 39 40 public class App 41 { 42 public App() 43 { 44 Test test = new Test(); 45 46 test.foo1 = Func; 47 test.foo1 += Func; 48 test.foo1(); 49 50 test.foo2 = Func;//这个会报错 51 test.foo2 += Func; 52 test.foo2();//这个会报错 53 } 54 55 public void Func() 56 { 57 Console.WriteLine("App Func"); 58 } 59 } 60 }