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