翼度科技»论坛 编程开发 .net 查看内容

C# - 委托与事件

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
委托与事件

委托

  查看代码
  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Publisher publisher = new Publisher("篮球先锋报");
  6.         Observer observerA = new Observer("老A");
  7.         publisher.Magazine += observerA.RecvMagazine;
  8.         Observer observerB = new Observer("老B");
  9.         publisher.Magazine += observerB.RecvMagazine;
  10.         publisher.PublishMagezine();
  11.         //或者使用下面的方式  区别就是一个在定义的内部触发,一个在外部触发
  12.         publisher.Magazine?.Invoke(publisher.magazineName);
  13.         Console.ReadKey();
  14.     }
  15. }
  16. public class Observer
  17. {
  18.     private string name;
  19.     public Observer(string name)
  20.     {
  21.         this.name = name;
  22.     }
  23.     public void RecvMagazine(string message)
  24.     {
  25.         Console.WriteLine($"{this.name} recv {message}, 仔细读了一番");
  26.     }
  27. }
  28. public class Publisher
  29. {
  30.     public string magazineName;
  31.     public Publisher(string magazineName)
  32.     {
  33.         this.magazineName = magazineName;
  34.     }
  35.     public delegate void MagazineDelegate(string message);
  36.     public MagazineDelegate Magazine;
  37.     public void PublishMagezine()
  38.     {
  39.         Magazine?.Invoke(this.magazineName);
  40.     }
  41. }
复制代码
事件

  查看代码
  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Publisher publisher = new Publisher("篮球先锋报");
  6.         Observer observerA = new Observer("老A");
  7.         publisher.Magazine += observerA.RecvMagazine;
  8.         Observer observerB = new Observer("老B");
  9.         publisher.Magazine += observerB.RecvMagazine;
  10.         publisher.PublishMagezine();
  11.         //下面的方式会出现编译错误  只允许在定义的内部触发,不允许在外部触发
  12.         publisher.Magazine?.Invoke(publisher.magazineName);
  13.         Console.ReadKey();
  14.     }
  15. }
  16. public class Observer
  17. {
  18.     private string name;
  19.     public Observer(string name)
  20.     {
  21.         this.name = name;
  22.     }
  23.     public void RecvMagazine(string message)
  24.     {
  25.         Console.WriteLine($"{this.name} recv {message}, 仔细读了一番");
  26.     }
  27. }
  28. public class Publisher
  29. {
  30.     public string magazineName;
  31.     public Publisher(string magazineName)
  32.     {
  33.         this.magazineName = magazineName;
  34.     }
  35.     public delegate void MagazineDelegate(string message);
  36.     public event MagazineDelegate Magazine;
  37.     public void PublishMagezine()
  38.     {
  39.         Magazine?.Invoke(this.magazineName);
  40.     }
  41. }
复制代码
经典面试题

猫叫、老鼠跑了,主人醒来了
  查看代码
  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Cat cat = new Cat();
  6.         Mouse m = new Mouse(cat);
  7.         People p = new People(cat);
  8.         cat.Scream();
  9.     }
  10. }
  11. public class Cat
  12. {
  13.     public delegate void ScreamHandler();
  14.     public event ScreamHandler OnScream;
  15.     public void Scream()
  16.     {
  17.         Console.WriteLine("猫叫了一声");
  18.         OnScream?.Invoke();
  19.     }
  20. }
  21. public class Mouse
  22. {
  23.     public Mouse(Cat c)
  24.     {
  25.         c.OnScream += () => { Console.WriteLine("老鼠跑了"); };
  26.     }
  27. }
  28. public class People
  29. {
  30.     public People(Cat c)
  31.     {
  32.         c.OnScream += () => { Console.WriteLine("主人醒来了"); };
  33.     }
  34. }
  35. //输出:
  36. //猫叫了一声
  37. //老鼠跑了
  38. //主人醒来了
复制代码
委托与事件的区别


  • 事件基于委托,但并非委托 可以把事件看成委托的代理。在使用者看来,只有事件,而没有委托。
  • 事件是对委托的包装 保护委托字段,对外不开放。所以外部对象没法直接操作委托。提供了Add和Remove方法,供外部对象订阅事件和取消事件。事件的处理方法在对象外部定义,而事件的执行是在对象的内部。至于事件的触发,何时何地无所谓。
什么时候使用委托与事件?

如果一个委托不需要再其定义的类之外被触发,那么就可以将其转化为事件,这样可以保证它不会在外部被随意触发。

来源:https://www.cnblogs.com/ShenhaoCore/p/18181643
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具