首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

对引发事件的步骤的疑问

2013-12-10 
对引发事件的方法的疑问写事件的时候一直迷迷糊糊的,这问题憋了好久,例子是这样的://烧水器(被观察者)publ

对引发事件的方法的疑问
写事件的时候一直迷迷糊糊的,这问题憋了好久,例子是这样的:

 
    //烧水器(被观察者)
    public class Heater
    {
        private int temperature;
        private string Place = "上海宝山";
        private string Time = "2013年11月7号";

        public delegate void BoiledEventHandler(object sender,BoiledEventArgs e);
        public event BoiledEventHandler Boiled;

        //定义BoiledEventArgs类,传递给Observer所感兴趣的信息
        public class BoiledEventArgs : EventArgs
        {
            public readonly int temperature;
            public readonly string Place;
            public readonly string Time;

            //构造函数
            public BoiledEventArgs(int temperature,string Place,string Time)
            {
                this.temperature = temperature;
                this.Place = Place;
                this.Time = Time;
            }
        }

        //可以供继承自 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,Place,Time);
                    OnBoiled(e);  // 调用 OnBolied方法
                }
            }
        }
    }



规范上给出这么写,但我不是太理解倒数第二个方法protected virtual void OnBoiled(BoiledEventArgs e)和最后一个烧水方法public void BoilWater()为什么要分开写。

如果合起来写成如何?

        //烧水
        public void BoilWater()
        {
            for (int i = 0; i <= 100; i++)
            {
                temperature = i;

                if (temperature > 95)
                {
                    //建立BoiledEventArgs 对象。
                    BoiledEventArgs e = new BoiledEventArgs(temperature,Place,Time);


                    if (Boiled != null)
                    {    // 如果有对象注册
                         Boiled(this, e);  // 调用所有注册对象的方法
                    }
                }
            }
        }
    }



例子里的注释说
//可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视


不是太理解,就算要重写,放在一个方法里面,用protected virtual不也可以?还是说这里面涉及到更高深的东西?


[解决办法]
这个和事件没有关系,这个叫NVI模式。

将公共方法放在基类中,并且写一个虚方法,完成操作,允许派生类重写改变实现。

http://en.wikipedia.org/wiki/Non-virtual_interface_pattern
http://tutorials.csharp-online.net/CSharp_Canonical_Forms%E2%80%94NVI_Pattern
http://acloudblog.blog.sohu.com/129992469.html


[解决办法]
如果你合起来写,我百分百地支持!

但是一些小事情不要太“洁癖”。事件往往被多个方法触发,那个时候就需要 OnXXX 这样分开写。因此此时就算多余地分开写了,也没有什么!

热点排行