AddMsg方法演示了一個恰當的方法來引發事件。臨時的日志句柄 變量 是很重要的,它可以確保在各種多線程的情況下,日志句柄也是安全的。 如果沒有這個引用的COPY,用戶就有可能在if檢測語句和正式執行事件句柄之間 移除事件句柄。有了引用COPY,這樣的事情就不會發生了。
我還定義了 一個LoggerEventArgs來保存事件和消息的優先級。委托定義了事件句柄的簽名 。而在Logger類的內部,事件字段定義了事件的句柄。編譯器會認為事件是公共 的字段,而且會為你添加Add和Remove兩個操作。生成的代碼與你這樣手寫的是 一樣的:
public class Logger
{
private AddMessageEventHandler _Log;
public event AddMessageEventHandler Log
{
add
{
_Log = _Log + value;
}
remove
{
_Log = _Log - value;
}
}
public void AddMsg (int priority, string msg)
{
AddMessageEventHandler l = _Log;
if (l != null)
l (null, new LoggerEventArgs (priority, msg));
}
}
}
C#編譯器創建Add和Remove操作來訪問事件。看到了嗎, 公共的事件定義語言很簡潔,易於閱讀和維護,而且更准確。當你在類中添加一 個事件時,你就讓編譯器可以創建添加和移除屬性。你可以,而且也應該,在有 原則要強制添加時自己手動的寫這些句柄。
事件不必知道可能成為監聽 者的任何資料,下面這個類自動把所有的消息發送到標准的錯誤設備(控制台)上 :
class ConsoleLogger
{
static ConsoleLogger ()
{
logger.Log += new AddMessageEventHandler( Logger_Log );
}
private static void Logger_Log( object sender,
LoggerEventArgs msg )
{
Console.Error.WriteLine( "{0}:\t{1}",
msg.Priority.ToString(),
msg.Message );
}
}