在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 Test18 {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 App39 {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 Test18 {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 App41 {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 }