黑马程序员--委托的好处与事件学习

------- Windows Phone 7手机开发.Net培训、期待与您交流! -------


声明委托的方式:delegate 返回值类型 委托类型名(参数) 比如delegate void StringProcess(string s); 注意这里的除了前面的delegate,剩下部分和声明一个函数一样,但是StringProcess不是函数名,而是委托类型名 


存储什么样的方法就声明什么类型(方法参数与返回值)的委托。
声明的委托是一种类型,就像int、Person一样,如果要用的话还要声明委托类型的变量,声明委托类型变量的方式:StringProcess f1;
将委托类型变量指向函数 StringProcess sp = new StringProcess(SayHello),这样就可以像调用普通函数一样把sp当成函数用了。


委托可以看做是函数的指针。整数可以用整数变量指向它,对象可以用对象变量指向它,函数也可以用委托变量指向它。

和直接调用函数的区别:用委托就可以指向任意的函数,哪怕是之前没定义的都可以,而不使用受限于那几种。
将委托类型变量指向函数还可以简化成StringProcess sp = SayHello,编译器帮我们进行了new。但是不能sp=PrintIt(),因为这样就成了函数调用。


委托类型的名称都应该以EventHandler结束。 委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。 事件的命名为 委托去掉 EventHandler之后剩余的部分。 继承自EventArgs的类型应该以EventArgs结尾。

  委托声明原型中的Object类型的参数代表了Subject,也就是监视对象,在本例中是 Heater(热水器)。回调函数(比如Alarm的MakeAlert)可以通过它访问触发事件的对象(Heater)。 EventArgs 对象包含了Observer所感兴趣的数据,在本例中是temperature。上面这些其实不仅仅是为了编码规范而已,这样也使得程序有更大的灵活性。比如说,如果我们不光想获得热水器的温度,还想在Observer端(警报器或者显示器)方法中获得它的生产日期、型号、价格,那么委托和方法的声明都会变得很麻烦,而如果我们将热水器的引用传给警报器的方法,就可以在方法中直接访问热水器了。


下面例子是一个实现烧水,并发出警报的模拟过程。现在假设热水器由三部分组成:热水器、警报器、显示器,它们来自于不同厂商并进行了组装。那么,应该是热水器仅仅负责烧水,它不能发出警报也不能显示水温;在水烧开时由警报器发出警报、显示器显示提示和水温。


警报器和显示器告诉热水器,它对它的温度比较感兴趣(注册)。 热水器知道后保留对警报器和显示器的引用。 热水器进行烧水这一动作,当水温超过95度时,通过对警报器和显示器的引用,自动调用警报器的MakeAlert()方法、显示器的ShowMsg()方 法。 类似这样的例子是很多的,GOF对它进行了抽象,称为Observer设计模式:Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 委托学习
{
    class DotNetFormal_Heater
    {
        private int tempterture;//温度
        public string type = "这是类型";//测试数据
        public string area = "大中华区产";//测试数据
        //声明委托
        public delegate void BoildEventHandler(Object sender, BoiledEventArgs e);
        public event BoildEventHandler Boiled;//声明事件
        /// <summary>
        /// 定义BoiledEventArgs类,传递Observer所感兴趣的信息
        /// </summary>
        public class BoiledEventArgs : EventArgs
        {
            public readonly int temperture;
            public BoiledEventArgs(int term)
            {
                this.temperture = term;
            }
        }
        /// <summary>
        /// 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视

        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnBoild(BoiledEventArgs e)
        {
            if (Boiled != null)//如果有对象注册
            {
                Boiled(this, e);//调用所有注册对象的方法
            }
        }
        /// <summary>
        /// 烧水
        /// </summary>
        public void BoilWater()
        {
            for (int i = 0; i <=100; i++)
            {
               this.tempterture  = i;
                if (tempterture>95)
                {
                    //建立建立BoiledEventArgs 对象。
                    BoiledEventArgs e = new BoiledEventArgs(this.tempterture);
                    OnBoild(e);//调用OnBolied方法
                }
            }
        }


    }
    //警报器的类
     class Alarm
    {
        public void MakeAlert(object sender,DotNetFormal_Heater.BoiledEventArgs e)
        {
            DotNetFormal_Heater heater = (DotNetFormal_Heater)sender;
            //访问 sender 中的公共字段
            Console.Write("Alarm:{0}--{1}", heater.area, heater.type);
            Console.WriteLine("Alarm:嘟嘟嘟,水已经{0}度了",e.temperture);

        }
    }
     class Display
    {
         public void ShowMsg(object sender, DotNetFormal_Heater.BoiledEventArgs e)
        {
            DotNetFormal_Heater heater = (DotNetFormal_Heater)sender;
            //访问 sender 中的公共字段
            Console.Write("Display:{0}--{1}", heater.area, heater.type);
            Console.WriteLine("Display:嘟嘟嘟,水快烧开了,当前温度是{0}度.", e.temperture);
        }
    }
     class program
     {
         static void Main()
         {
             DotNetFormal_Heater heater = new DotNetFormal_Heater();
             Alarm alarm=new Alarm ();
             heater.Boiled += alarm.MakeAlert;//警报器和显示器告诉热水器,它对它的温度比较感兴趣(注册)。
             heater.Boiled+=(new Display()).ShowMsg;//给匿名对象注册方法
           //  heater.Boiled += new DotNetFormal_Heater.BoildEventHandler(alarm.MakeAlert);
             heater.BoilWater();
             Console.ReadKey();
         }
     }
}


------- Windows Phone 7手机开发.Net培训、期待与您交流! -------


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值