我想听听以下代码段的意见。有什么可以改进的吗?事件处理程序/提升者是否遵循最佳做法?
我知道在同一个类中处理和引发事件并没有那么有用。但是这只是一个片段。public class MyControl
{
public MyControl()
{
this.LogWritten += this.HandleMyControlLogWritten;
}
// Event handler
void HandleMyControlLogWritten(object sender, EventArgs e)
{
}
// Event object
public event Action<object, EventArgs> LogWritten;
// Event raiser
protected virtual void OnLogWritten(EventArgs e)
{
if (this.LogWritten != null)
{
this.LogWritten(this, e);
}
}
}
答案 0 :(得分:6)
我建议的主要变化是获取事件处理程序的副本:
// Event raiser
protected virtual void OnLogWritten(EventArgs e)
{
var handler = this.LogWritten;
if (handler != null)
{
handler(this, e);
}
}
如果您计划(最终)在多线程场景中使用此类,这一点非常重要。因此,我发现养成使用习惯是一种很好的“最佳实践”。问题是,当在多个线程中使用而不创建副本时,附加的唯一“处理程序”可能会取消订阅空检查和调用,这将导致运行时错误。通过复制到临时变量(var handler = this.LogWritten;
)行,您可以有效地创建订阅者列表的“快照”,然后然后将其检查为null并在需要时调用。
另一个变化是事件声明本身。而不是使用Action<T1,T2>
:
// Event object
public event Action<object, EventArgs> LogWritten;
我建议您使用EventHandler<TEventArgs>
(如果您想使用自定义EventArgs
子类)或EventHandler
(标准EventArgs
)。这些是更“标准的做法”,并且将是其他开发人员所期望的:
// Event object
public event EventHandler LogWritten;