黑马程序员技术交流社区

标题: 委托和事件 [打印本页]

作者: 宋天琪    时间: 2011-11-4 21:34
标题: 委托和事件
本帖最后由 宋天琪 于 2012-2-2 12:10 编辑

各位高手,帮忙讲一下。。最好举例说明一下
作者: 何荣智    时间: 2011-11-5 01:21
using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate {
    // 热水器
    public class Heater {
       private int temperature;
       public string type = "RealFire 001";       // 添加型号作为演示
       public string area = "China Xian";         // 添加产地作为演示
       //声明委托
       public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);
       public event BoiledEventHandler Boiled; //声明事件

       // 定义BoiledEventArgs类,传递给Observer所感兴趣的信息
       public class BoiledEventArgs : EventArgs {
           public readonly int temperature;
           public BoiledEventArgs(int temperature) {
              this.temperature = temperature;
           }
       }

       // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
       protected virtual void OnBoiled(BoiledEventArgs e) {
           if (Boiled != null) { // 如果有对象注册
              Boiled(this, e);  // 调用所有注册对象的方法
           }
       }
      
       // 烧水。
       public void BoilWater() {
           for (int i = 0; i <= 100; i++) {
              temperature = i;
              if (temperature > 95) {
                  //建立BoiledEventArgs 对象。
                  BoiledEventArgs e = new BoiledEventArgs(temperature);
                  OnBoiled(e);  // 调用 OnBolied方法
              }
           }
       }
    }

    // 警报器
    public class Alarm {
       public void MakeAlert(Object sender, Heater.BoiledEventArgs e) {
           Heater heater = (Heater)sender;     //这里是不是很熟悉呢?
           //访问 sender 中的公共字段
           Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
           Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature);
           Console.WriteLine();
       }
    }

    // 显示器
    public class Display {
       public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) {   //静态方法
           Heater heater = (Heater)sender;
           Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
           Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);
           Console.WriteLine();
       }
    }

    class Program {
       static void Main() {
           Heater heater = new Heater();
           Alarm alarm = new Alarm();

           heater.Boiled += alarm.MakeAlert;   //注册方法
           heater.Boiled += (new Alarm()).MakeAlert;      //给匿名对象注册方法
           heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert);    //也可以这么注册
           heater.Boiled += Display.ShowMsg;       //注册静态方法

           heater.BoilWater();   //烧水,会自动调用注册过对象的方法
       }
    }
}

输出为:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Display:China Xian - RealFire 001:
Display:水快烧开了,当前温度:96度。
// 省略 ...


作者: 何荣智    时间: 2011-11-5 01:31
•委托类型的名称都应该以EventHandler结束。
•委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。
•事件的命名为 委托去掉 EventHandler之后剩余的部分。
•继承自EventArgs的类型应该以EventArgs结尾。
再做一下说明:

1.委托声明原型中的Object类型的参数代表了Subject,也就是监视对象,在本例中是 Heater(热水器)。回调函数(比如Alarm的MakeAlert)可以通过它访问触发事件的对象(Heater)。
2.EventArgs 对象包含了Observer所感兴趣的数据,在本例中是temperature。

作者: 郑文    时间: 2011-11-5 01:42
都是抄袭的张子阳的博客 , 这个问题你最好去看张子阳的博客 百度就能找到,委托与事件不是一两句就能说清楚的。看他的博客的前是 你对C#已经有了基本的认识,否则根本看不懂他在讲什么。 我建议,如果你是一个初学者,先不要研究那么深,等代码写多了,再去研究委托那些东西,否则基础不好很容易晕。
作者: 李波    时间: 2011-12-4 21:02
推荐你一个帖子: 委托 事件 监听
http://topic.csdn.net/u/20110331/15/29b5b7c8-e500-40b2-98db-17ff8b48fb7c.html
作者: 付炯    时间: 2011-12-4 22:53
委托是提供对具有特定返回类型和参数列表方法一般引用的引用类型 在多线程编程中用于指定启动线程时调用的方法 在异步编程中常用作回调函数
引用多个方法的委托称为多播委托 调用时连续调用每个方法 其中每个委托必须是同类型的 且返回值为void
C#使用委托模型实现事件 使事件的处理方法不必在生成事件的类中定义 即可以将事件处理程序放在不同类中
实现了在不改变事件源类结构的情况下改变事件处理程序
写了这么多 还是建议你找一本参考书看看 结合代码学习一下
作者: 陆亚    时间: 2011-12-6 14:58
http://blog.csdn.net/luya1990/article/details/7046090

我刚写的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2