模拟这样一个情景。一个加热器(Heater)和一个冷却器(Cooler)连接到一个温度自动调节器。当温度变化时,温度调节器把温度传给它的订阅者,也就是Heater和Cooler
Heater类
class Heater
{
private int _Temperature;
public Heater(int Temperature)
{
_Temperature = Temperature;
}
public int Temperature
{
get
{
return _Temperature;
}
set
{
_Temperature = value;
}
}
public void OnTemperatureChanged(int NewTemperature)
{
if (NewTemperature > _Temperature)
{
Console.WriteLine("Heater On");
}
else
{
Console.WriteLine("Heater Off");
}
}
}
Cooler类
class Cooler
{
private int _Temperature;
public Cooler(int Temperature)
{
_Temperature=Temperature;
}
public int Temperature
{
get
{
return _Temperature;
}
set
{
_Temperature=value;
}
}
public void OnTemperatureChanged(int NewTemperature)
{
if (NewTemperature < _Temperature)
{
Console.WriteLine("Cooler On");
}
else
{
Console.WriteLine("Cooler Off");
}
}
}
发布者(温度调节器)
public class Thermostate
{
public delegate void TemperatureChangedHandle(int NewTemperature);
private int _Temperature;
private TemperatureChangedHandle _OnTemperatureChanged;
public TemperatureChangedHandle OnTemperatureChanged
{
get { return _OnTemperatureChanged; }
set { _OnTemperatureChanged = value; }
}
public int Temperature
{
get { return _Temperature; }
set
{
if (value != _Temperature)
{
_Temperature = value;
TemperatureChangedHandle tmpOnTemperatureChanged = _OnTemperatureChanged;
if (tmpOnTemperatureChanged != null)
{
tmpOnTemperatureChanged(_Temperature);
}
}
}
}
}
在Main函数中让Heater和Cooler的实例订阅Thermostat
class Program
{
static void Main(string[] args)
{
Thermostate thermostat = new Thermostate();
Cooler cooler = new Cooler(60);
Heater heater = new Heater(80);
string Temperature;
thermostat.OnTemperatureChanged += cooler.OnTemperatureChanged;
thermostat.OnTemperatureChanged += heater.OnTemperatureChanged;
Temperature = Console.ReadLine();
thermostat.Temperature = Convert.ToInt32(Temperature);
}
}
注意Thermostat类的实现中,当温度改变时,调用委托的实例。但是在调用之前要先判断一下委托是否为空,如果为空,调用时就会引发异常。
判断委托是否为空时,我先把当前的委托赋值给了另外一个委托变量。这个简单的修改可以确保在检查空值和发送通知之间,假如所有的订阅者都被移除了(由另外一个不同的县城),那么也不会触发异常。
(为什么呢?我把当前的委托赋值给了一个局部委托变量,那么这两个委托不是应该指向同一个引用吗?如果一个改变为空了,另一个不是也为空了吗?事实上,当在_OnTemperatureChanged上调用-=时,并没有直接修改_OnTemperatureChanged所引用的对象,而是返回了一个新的委托对象,有点像String类型。所以_OnTemperatureChanged上调用-=时,tmpTemperatureChanged并没有变化)
切记:调用委托前,先检查它的值是否为空