顽强的生命力 发表于 2024-5-9 16:46:49

C# - 委托与事件

委托与事件

委托

查看代码class Program
{
    static void Main(string[] args)
    {
      Publisher publisher = new Publisher("篮球先锋报");

      Observer observerA = new Observer("老A");
      publisher.Magazine += observerA.RecvMagazine;

      Observer observerB = new Observer("老B");
      publisher.Magazine += observerB.RecvMagazine;

      publisher.PublishMagezine();
      //或者使用下面的方式区别就是一个在定义的内部触发,一个在外部触发
      publisher.Magazine?.Invoke(publisher.magazineName);
      Console.ReadKey();
    }
}

public class Observer
{
    private string name;
    public Observer(string name)
    {
      this.name = name;
    }

    public void RecvMagazine(string message)
    {
      Console.WriteLine($"{this.name} recv {message}, 仔细读了一番");
    }
}

public class Publisher
{
    public string magazineName;
    public Publisher(string magazineName)
    {
      this.magazineName = magazineName;
    }

    public delegate void MagazineDelegate(string message);
    public MagazineDelegate Magazine;

    public void PublishMagezine()
    {
      Magazine?.Invoke(this.magazineName);
    }
}事件

查看代码class Program
{
    static void Main(string[] args)
    {
      Publisher publisher = new Publisher("篮球先锋报");

      Observer observerA = new Observer("老A");
      publisher.Magazine += observerA.RecvMagazine;

      Observer observerB = new Observer("老B");
      publisher.Magazine += observerB.RecvMagazine;

      publisher.PublishMagezine();
      //下面的方式会出现编译错误只允许在定义的内部触发,不允许在外部触发
      publisher.Magazine?.Invoke(publisher.magazineName);
      Console.ReadKey();
    }
}

public class Observer
{
    private string name;
    public Observer(string name)
    {
      this.name = name;
    }

    public void RecvMagazine(string message)
    {
      Console.WriteLine($"{this.name} recv {message}, 仔细读了一番");
    }
}

public class Publisher
{
    public string magazineName;
    public Publisher(string magazineName)
    {
      this.magazineName = magazineName;
    }

    public delegate void MagazineDelegate(string message);
    public event MagazineDelegate Magazine;

    public void PublishMagezine()
    {
      Magazine?.Invoke(this.magazineName);
    }
}经典面试题

猫叫、老鼠跑了,主人醒来了
查看代码class Program
{
    static void Main(string[] args)
    {
      Cat cat = new Cat();
      Mouse m = new Mouse(cat);
      People p = new People(cat);
      cat.Scream();
    }
}

public class Cat
{
    public delegate void ScreamHandler();
    public event ScreamHandler OnScream;

    public void Scream()
    {
      Console.WriteLine("猫叫了一声");
      OnScream?.Invoke();
    }

}

public class Mouse
{
    public Mouse(Cat c)
    {
      c.OnScream += () => { Console.WriteLine("老鼠跑了"); };
    }
}

public class People
{
    public People(Cat c)
    {
      c.OnScream += () => { Console.WriteLine("主人醒来了"); };
    }
}

//输出:
//猫叫了一声
//老鼠跑了
//主人醒来了委托与事件的区别


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

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

来源:https://www.cnblogs.com/ShenhaoCore/p/18181643
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: C# - 委托与事件