zoukankan      html  css  js  c++  java
  • 委托与事件

    .net中委托与事件的编程规范:

    1.委托的名称都应该以EventHandler结束

    2.委托的原型定义:有一个void返回值.并接受两个输入参数:一个Object类型的参数,一个EventArgs类型(或继承自EventArgs)

    3.事件的命名为 委托去掉EventHandler之后的部分

    4.继承自EventArgs的类型应该以EventArgs结尾

    说明:

    1.委托中的Object类型的参数为引发事件的对象.

    2.EventArgs对象应包含事件处理对象所需要的数据.

    见下例,对下例该如何改造:

    public class Heater
    {
        public int temp=0;
    
        public event BoilHandler BoilEvent;
        public void BoilWater()
        {
            for (; temp <= 100; temp++)
            {
                if (temp >= 96)
                {
                    if (BoilEvent != null)
                    {
                        BoilEvent(temp);
                    }
                }
            }
        }
    }
    
    public delegate void BoilHandler(int temp);
    public class Alarm
    {
        public void MakeAlert(int temp)
        {
            HttpContext.Current.Response.Write("警告:现在温度是" + temp.ToString() + "<br/>");
        }
    }
    
    public class Display
    {
        public void ShowMsg(int temp)
        {
            HttpContext.Current.Response.Write("提示:水开了.温度是" + temp.ToString() + "<br/>");
        }
    }

    页面调用:

        protected void Page_Load(object sender, EventArgs e)
        {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();
            Display display = new Display();
    
            heater.BoilEvent += alarm.MakeAlert;
            heater.BoilEvent += display.ShowMsg;
            heater.BoilWater();        
        }

    若使用委托,按照编码规范,改造如下:

    public class Heater
    {
        public int temp;
        public Heater(int temp)
        {
            this.temp = temp;
        }
    
        public delegate void BoilEventHandler(Object sender,BoiledEventArgs e);
        public event BoilEventHandler Boil;
    
        public void BoilWater()
        {
            for (; temp <= 100; temp++)
            {
                if (temp >= 96)
                {
                    BoiledEventArgs e = new BoiledEventArgs(temp);
                    if (Boil != null)
                    {
                        Boil(this, e);
                    }
                }
            }
        }
    }
    
    public class BoiledEventArgs : EventArgs
    {
        public int temp;
        public BoiledEventArgs(int temp)
        {
            this.temp = temp;
        }
    }
    
    public class Alarm
    {
        public void MakeAlert(Object sender,BoiledEventArgs e)
        {
            Heater heater = (Heater)sender;
            HttpContext.Current.Response.Write("警告:现在温度是" + heater.temp.ToString() + "<br/>");
        }
    }

    若不使用委托,用观察者模式,改造如下:

    public class HeaterSubject
    {
        int temp=0;
        ArrayList observers;
        public HeaterSubject()
        {
            observers = new ArrayList();
        }
    
        public void AddObserver(Observer observer)
        {
            this.observers.Add(observer);
        }
    
        public void RemoveObserver(Observer observer)
        {
            observers.Remove(observer);
        }
    
        public void BoilWater()
        {
            for (; temp <= 100; temp++)
            {
                if (temp >= 96)
                {
                    Notice(temp);
                }
            }
        }
    
        void Notice(int temp)
        {
            foreach (Observer observer in observers)
            {
                observer.Update(temp);
            }
        }
    
    }
    
    public interface Observer
    {
        void Update(int temp);
    }
    
    public class AlarmObserver : Observer
    {
        public void Update(int temp)
        {
            HttpContext.Current.Response.Write("警告:现在温度是" + temp.ToString() + "<br/>");
        }
    }
    
    public class DisplayObserver : Observer
    {
        public void Update(int temp)
        {
            HttpContext.Current.Response.Write("提示:水开了.温度是" + temp.ToString() + "<br/>");
        }
    }

    比较:

    使用委托,则事件处理对象的方法名可以和委托不一致,但是签名需匹配.

    使用观察者模式,事件处理对象需实现同一个接口.

    何时使用委托?何时使用接口?

    在以下情况中使用委托:

    • 当使用事件设计模式时。

    • 当封装静态方法可取时。

    • 当调用方不需要访问实现该方法的对象中的其他属性、方法或接口时。

    • 需要方便的组合。

    • 当类可能需要该方法的多个实现时。

    在以下情况中使用接口:

    • 当存在一组可能被调用的相关方法时。

    • 当类只需要方法的单个实现时。

    • 当使用接口的类想要将该接口强制转换为其他接口或类类型时。

    • 当正在实现的方法链接到类的类型或标识时:例如比较方法

  • 相关阅读:
    相似数据检测算法
    从一个简单的程序中你能看到什么?(面向对象的真帝)
    如何更好的理解类和结构
    从一个很简单的文件上传来品味面向对象的大局观(抽象类和功能类)
    网站中的缩略图是如何生成的?(C#处理图像)
    进程间通信(一)
    POSIX线程-(六)
    进程间通信(四)
    进程间通信(三)
    POSIX线程-(五)
  • 原文地址:https://www.cnblogs.com/oneword/p/1683934.html
Copyright © 2011-2022 走看看