模擬這樣一個情景。一個加熱器(Heater)和一個冷卻器(Cooler)連接到一個溫度自動調(diào)節(jié)器。當溫度變化時,溫度調(diào)節(jié)器把溫度傳給它的訂閱者,也就是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");
}
}
}
發(fā)布者(溫度調(diào)節(jié)器)
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函數(shù)中讓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類的實現(xiàn)中,當溫度改變時,調(diào)用委托的實例。但是在調(diào)用之前要先判斷一下委托是否為空,如果為空,調(diào)用時就會引發(fā)異常。
判斷委托是否為空時,我先把當前的委托賦值給了另外一個委托變量。這個簡單的修改可以確保在檢查空值和發(fā)送通知之間,假如所有的訂閱者都被移除了(由另外一個不同的縣城),那么也不會觸發(fā)異常。
(為什么呢?我把當前的委托賦值給了一個局部委托變量,那么這兩個委托不是應(yīng)該指向同一個引用嗎?如果一個改變?yōu)榭樟耍硪粋€不是也為空了嗎?事實上,當在_OnTemperatureChanged上調(diào)用-=時,并沒有直接修改_OnTemperatureChanged所引用的對象,而是返回了一個新的委托對象,有點像String類型。所以_OnTemperatureChanged上調(diào)用-=時,tmpTemperatureChanged并沒有變化)
切記:調(diào)用委托前,先檢查它的值是否為空