事件处理程序/提升程序代码段

Teo*_*gul 2 c# events conventions

我想听听下面代码片段的意见.有什么可以改进的吗?事件处理程序/提升者是否遵循最佳做法?我知道在同一个类中处理和引发事件并没有那么有用,但这只是一个片段.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 6

我建议的主要变化是获取事件处理程序的副本:

// Event raiser
protected virtual void OnLogWritten(EventArgs e)
{
    var handler = this.LogWritten;
    if (handler != null)
    {
        handler(this, e);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您计划(最终)在多线程场景中使用此类,这一点很重要.因此,我发现养成使用习惯是一种很好的"最佳实践".问题是,当在多个线程中使用而不创建副本时,附加的唯一"处理程序"可能会取消订阅空检查和调用,这将导致运行时错误.通过复制到临时变量(行var handler = this.LogWritten;),您可以有效地创建订户列表的"快照",然后检查它是否为null并在需要时调用.

另一个变化是事件声明本身.而不是使用Action<T1,T2>:

// Event object
public event Action<object, EventArgs> LogWritten;
Run Code Online (Sandbox Code Playgroud)

我建议使用EventHandler<TEventArgs>(如果你想使用自定义EventArgs子类)或EventHandler(标准EventArgs).这些是更"标准的做法",并将成为其他开发人员所期望的:

// Event object
public event EventHandler LogWritten;
Run Code Online (Sandbox Code Playgroud)

  • 虽然我同意,但可能值得解释*为什么*这是一个好主意. (2认同)