• Use the Delegate Or Event ?


      最初接触委托(Delegate)与事件(Event)时,始终对两者应用上不能做出较好的区分。只是事件自身是借助于委托实现的,那么如果委托足以应对大多数的需求,那么为什么引入事件呢?(Why Events)这样想来似乎陷入了“既生瑜,何生亮”的慨叹中...暂且打住,看看具体的事例情况吧:

    // 发布事件的Clock类 Clock.cs

    代码
    public class Clock
    {
    public delegate void TimeHandler(string curTime);
    public event TimeHandler ShowTime;
    //public TimeHandler ShowTime;

    private string time;

    public Clock()
    {
    time
    = "09.03.14";
    }

    public string Time
    {
    get { return time; }
    set
    {
    if (value != null)
    {
    time
    = value;
    }
    }
    }

    public void ChangeTime(string tm)
    {
    ShowTime(tm);
    }
    }

    // 订阅事件的TimeBoard类 TimeBoard.cs

    public class TimeBoard
    {
    public void DisplayTime(string timeToShow)
    {
    Console.WriteLine(
    "Time on the Board :{0}", timeToShow);
    }
    // ...
    }

    // 订阅事件的TimeWriter类 TimeWriter.cs

    代码
    public class TimeWriter
    {
    public void RecordTime(string timeToRecord)
    {
    Console.WriteLine(
    "Time in the Logger :{0}", timeToRecord);
    }
    // ...
    }

    // 进行测试的主函数部分 Program.cs

    代码
    static void Main(string[] args)
    {
    Clock clock
    = new Clock();

    TimeBoard tb
    = new TimeBoard();
    TimeWriter tw
    = new TimeWriter();

    clock.ShowTime
    += new Clock.TimeHandler(tb.DisplayTime);

    // How about this one?
    //clock.TimeShow = new Clock.TimeHandler(tw.RecordTime);

    clock.ShowTime
    += new Clock.TimeHandler(tw.RecordTime);
    Console.WriteLine(
    "The current time :{0}", clock.Time);
    Console.WriteLine(
    "After the change:");
    clock.ChangeTime(
    "09.3.16");

    //Console.WriteLine("After the second change:");
    //clock.ShowTime("09.3.20");// Error!
    }

      (注意被注释掉的没有加上event 关键字声明的那一行) 如果只是应用delegate,对应看到Main函数中,当TimeWriter对象注册事件时,一旦误用了赋值操作符"=",而不是"+="添加方法到事件链中时会使在这之前已经注册的方法变成无效(被擦除掉),而这并非我们操作的本意。但以event 关键字进行声明后,编译器能自动检测出此处的误用,这正是event体现出的更好的封装性。

      另外值得注意的一点是,如果最后Main函数中(最后一行的代码)clock似乎绕到了后方,开始直接调用自身对外公开的delegate,同时传入虚假的参数试图触发整个调用链。同样如果应用event代替delegate进行处理,此处的非法调用会被C#编译器侦查到,报告错误信息,提示调用出错。而这一点正是保证了委托所封装的方法只在发布事件的那一端得到触发时才真正被调用,隔绝了从外部调用的可能性。

      最后以它们各自想表达的话语作结吧  :-)

      Delegate 告诉另外的一个类“执行这个操作,做完后这个通知我”。Event 在一旁也说了“没有这么简单,我负责的这个delegate所封装的方法是专为个人处理而使用的:可以订阅/退订,而不可以直接经外部调用”。

  • 相关阅读:
    LAMP
    监控和安全运维 1.8 zabbix服务端安装
    监控和安全运维 1.7 nagios配置邮件告警
    易道用车-拿什么说爱你
    unix exec族函数 关于参数的疑惑
    关于 Unix 用户权限及进程权限及 Saved set-user-id
    ANSI C中关于FILE流的一些
    Filco minila 的蛋疼。
    IIS32位,64位模式下切换
    Gvim+Emmet.vim 那些事。
  • 原文地址:https://www.cnblogs.com/raywalker/p/1669369.html
Copyright © 2020-2023  润新知