C#中的委托和事件

    委托类似于C++中的函数指针,C#中的委托申明如下:

    delegate void MyDelegate();

    只要该委托执行的方法与委托申明的签名一致,就能调用委托来执行该方法,例如在本例中,有个方法为:

    void Method();那么就可以如下调用:

    MyDelegate _delegate = new MyDelegate(Method);

    _delegate();

    这样做的好处在于,我只需要知道调用的方法的签名,而具体的方法调用可以等到运行的时候用委托去绑定。例如C#高级编程中的举例,对于一个冒泡排序算法,可能是对一个整数数组排序,也可能是对对象进行排序,所以排序算法进行比较的时候就不能单纯的用>=<等去判断。不同的数组其比较的方式不一样,那么我只要在排序算法中使用委托,而在具体的调用时候传递具体的函数即可。具体请参考C#高级编程委托和事件相关章节。

    另:委托在C#中被当做是一个类。

    事件和委托结合起来使用,构成了windows界面编程的基础。事件的申明如下:

    event MyDelegate myEvent;// 与MyDelegate相关的事件

    事件可以看成是一个委托变量,事件-委托-方法的关系是:将某个方法注册到事件中,当事件被调用的时候,和事件相关的委托就会去调用注册的方法。

    举个例子:在医院里,医生并不需要时时刻刻盯着病人,我们假定病人在出现问题的时候,就会通过某种方式(按铃呼叫)通知相关的医生。对应上面的关系,事件即是病人按铃呼叫医生,医生接收到病人的呼叫并能进行处理。

    我们使用了两个类Patient类和Doctor类。在Patient类里面有个Emergency的方法,表示需要呼叫医生,会触发呼叫事件。在Doctor类中有个Response方法,表示医生接收到病人的呼叫,采取相应的措施。因为在实际中,Patient可能并不知道Doctor的Response方法,所以在Emergency方法里面直接调用Response是不现实的,而且造成两者的耦合性太高,此外,如果病人需要呼叫的不是医生,那么。。。混乱吧。

    下面轮到委托和事件出场了。我们定义了一个委托:

public delegate void CallDoctorHander(object sender, CallDoctorEventArgs e);

    sender表示事件的发起者(此例为病人),e表示事件的相关信息(在此处可能是病人的相关信息,如病人姓名和房号等)。CallDoctorEvnetArgs表示与病人信息相关的类,事件触发的时候,相关信息也进行传递。

// 定义一个相关事件的类,存储病人的相关信息
    public class CallDoctorEventArgs : EventArgs
    {
        string _msg = ""; // 存储病人的信息,例如房号和病人名称
        public CallDoctorEventArgs()
        {

        }

        public CallDoctorEventArgs(string msg)
        {
            _msg = msg;
        }

        public string Message
        {
            set
            {
                _msg = value;
            }
            get
            {
                return _msg;
            }
        }
    }
    然后在Patient类中定义一个事件,并在Emergency方法中触发这个事件,注意,我们并不知道谁会响应这个事件,实际上,这也不是Patient类所要关注的事情。

public class Patient
    {
        private string _name;
        private string _roomNumber;
        public Patient()
        {
            _name = "Jerry";
            _roomNumber = "1";
        }

        public Patient(string name, string roomNum)
        {
            _name = name;
            _roomNumber = roomNum;
        }

        public static event CallDoctorHander CallDoctor; // 定义事件,为委托CallDoctorHander的变量

        // 一旦发生紧急状况,需要调用呼叫函数
        // 对于Patient类,它并不知道具体执行的是哪个函数,只知道函数的形式
        public void Emergency()
        {
            // 调用呼叫医生函数
            // 初始化相关的病人信息
            CallDoctorEventArgs ev = new CallDoctorEventArgs();
            ev.Message = "Patient Name: " + _name + "\nRoom Number: " + _roomNumber;
            if (CallDoctor != null)
                CallDoctor(this, ev);
        }
    }
    实际上,响应该事件的应该是Doctor中的方法。

public class Doctor
    {
        // 医生对病人呼叫的响应
        public void Response(object sender, CallDoctorEventArgs ev)
        {
            Console.WriteLine("Sender: " + sender.ToString());
            Console.WriteLine(ev.Message);
        }
    }
    那么,如何让CallDoctor事件发生时候,Doctor会调用Response方法响应呢?答案是通过将方法通过委托注册到事件中。

	    Doctor dct = new Doctor();
            Patient pt = new Patient();
            Patient.CallDoctor += new CallDoctorHander(dct.Response);// 注册方法到事件
            pt.Emergency();
    这样,一旦调用了Emergency方法,就会触发事件CallDoctor,然后通过委托调用注册了的方法。

    执行结果:

    

   

    PS:感觉自己大概理解了委托和事件,但是要详细的讲清楚还是得磨练。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值