我试图正确理解EventsEventArgs,但不能完全理解整个EventArgs.Empty属性。

EventArgs实现:

public static readonly EventArgs Empty;


并允许我们创建一个EventHandler并使用以下命令进行调用:

public event EventHandler<EventArgs> TestHappening;

private void MyMethod()
{
    TestHappening( this, EventArgs.Empty );
}


现在,我研究了许多基于EventArgs的类,它们似乎都没有实现此目的,因此即使我已经阅读了有关EventArgs.Empty的所有文档,但我还是有点盲目。根据文档,“ Empty的值是EventArgs的只读实例,等效于调用EventArgs构造函数的结果”。

基于此,我创建了以下实现:

public class TestEventArgs : EventArgs
{
    public static readonly TestEventArgs Empty;

    public bool UpdatedValue { get; private set; }

    TestEventArgs()
        : this( false )
    {
    }

    public TestEventArgs( bool updatedValue )
    {
        this.UpdatedValue = updatedValue;
    }
}

public event EventHandler<TestEventArgs> TestHappening;

private void MyMethod()
{
    TestHappening( this, EventArgs.Empty );
}


使用TestEventArgs.Empty实例化一个类还是它在做什么?

而且,即使我检查的所有子类都没有使用Empty,它们仍然可用,难道暴露了不可用的属性会令人困惑吗?

最后,根据我研究的各种文档,实际实例化EventArgs的时间有两个主要差异。哪个被认为“更”正确?

OnTestHappening( new TestEventArgs( false ) );

private void OnTestHappening( TestEventArgs e )
{
    var handler = TestHappening;

    if ( handler != null )
        handler( this, e );
}




OnTestHappening( true );

private void OnTestHappening( bool foo )
{
    var handler = TestHappening;

    if ( handler != null )
        handler( this, new TestEventArgs( foo ) );
}

最佳答案

如果确实需要Empty字段,则应自己考虑。如果您不使用它,则不应该创建它。 EventArgs类没有任何变量或属性,因此每次创建一个新实例都没有意义。在您的情况下,由于您具有默认值,所以有两个“空” TestEventArgs确实更有意义,一个为true,一个为false(如果您确实愿意,并且在您的情况下很有意义) )。

您在实现中遗漏了一些其他问题,以下是我已解决的问题:

public class TestEventArgs : EventArgs
{
    public static readonly TestEventArgs True = new TestEventArgs(true);

    public static readonly TestEventArgs False = new TestEventArgs(false);

    public bool UpdatedValue { get; private set; }

    public TestEventArgs(bool updatedValue)
    {
        this.UpdatedValue = updatedValue;
    }

    public event EventHandler<TestEventArgs> TestHappening;

    private void MyMethod()
    {
        EventHandler<TestEventArgs> eh = TestHappening;

        eh?.Invoke(this, TestEventArgs.True);
    }
}


我改变了什么:


Empty实例化为new TestEventArgs,因为这也是EventArgs.Empty的定义。
我已经实现了事件处理程序的线程安全版本(代码中的第二个示例)。如果订阅该事件的事件处理程序列表发生了变化,那么您的第一个示例是不安全的。您的第二个是,因此您应该选择该选项。


关于最后一点:这取决于您是否打算让调用委托更改对象(它传递一个实例还是多个实例)。在您的情况下,由于不能更改实例,所以没关系。

关于c# - 正确实现EventArgs为空,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30597904/

10-11 12:27