读书人

对引发事件的步骤的疑问

发布时间: 2013-12-10 15:05:55 作者: rapoo

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

 
//烧水器(被观察者)
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 这样分开写。因此此时就算多余地分开写了,也没有什么!

读书人网 >C#

热点推荐