Effective C# 原则22:用事件定义对外接口
2009-02-19 08:16:32 来源:WEB开发网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 );
}
}
- ››Effective C# 原则40:根据需求选择集合
- ››Effective C# 原则41:选择DataSet而不是自定义的...
- ››Effective C# 原则42:使用特性进行简单的反射
- ››Effective C# 原则43:请勿滥用反射
- ››Effective C# 原则44:创建应用程序特定的异常类
- ››Effective C# 第6章:杂项
- ››Effective C# 原则45:选择强异常来保护程序
- ››Effective C# 原则47:选择安全的代码
- ››Effective C# 原则48:了解更多的工具和资源
- ››Effective C# 原则49:为C#2.0做好准备
- ››Effective C# 原则50:了解ECMA标准
- ››Effective C# 原则系列文章目录
更多精彩
赞助商链接