正确实现 EventArgs Empty
Implementing EventArgs Empty Correctly
我正在尝试正确理解 Events
和 EventArgs
,但无法完全掌握 EventArgs.Empty
属性.
EventArgs
实现:
public static readonly EventArgs Empty;
并允许我们创建一个 EventHandler
并使用以下方式调用它:
public event EventHandler<EventArgs> TestHappening;
private void MyMethod()
{
TestHappening( this, EventArgs.Empty );
}
现在我已经研究了一些基于 EventArgs
and none of them seem to implement this so I'm flying a little blind even though I've read all the documentation I could find regarding EventArgs.Empty
的 classes。根据文档,"The value of Empty is a read-only instance of EventArgs equivalent to the result of calling the EventArgs constructor"。
基于此,我创建了以下实现:
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
的使用是在实例化一个 class 还是它到底在做什么?
此外,尽管我检查的所有子classes 都没有使用 Empty
,但它们仍然可用,不可用的 [=47= 是不是很混乱? ] 暴露了?
最后,根据我研究的各种文档,实际实例化 EventArgs
的时间有两个主要差异。哪个被认为是 "more" 正确的?:
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
class 没有任何变量或属性,因此每次都创建一个新实例没有意义。在你的情况下,因为你有一个默认值,所以有两个 'empty' 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
的定义。
- 我已经实现了事件处理程序的线程安全版本(您的代码中的第二个示例)。如果订阅事件的事件处理程序列表发生变化,则您的第一个示例不安全。你的第二个是,因此你应该选择那个。
关于你的最后一点:这取决于你是否打算让调用委托更改对象(它是传递一个实例还是传递多个实例)。在您的情况下,由于无法更改实例,所以没关系。
我正在尝试正确理解 Events
和 EventArgs
,但无法完全掌握 EventArgs.Empty
属性.
EventArgs
实现:
public static readonly EventArgs Empty;
并允许我们创建一个 EventHandler
并使用以下方式调用它:
public event EventHandler<EventArgs> TestHappening;
private void MyMethod()
{
TestHappening( this, EventArgs.Empty );
}
现在我已经研究了一些基于 EventArgs
and none of them seem to implement this so I'm flying a little blind even though I've read all the documentation I could find regarding EventArgs.Empty
的 classes。根据文档,"The value of Empty is a read-only instance of EventArgs equivalent to the result of calling the EventArgs constructor"。
基于此,我创建了以下实现:
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
的使用是在实例化一个 class 还是它到底在做什么?
此外,尽管我检查的所有子classes 都没有使用 Empty
,但它们仍然可用,不可用的 [=47= 是不是很混乱? ] 暴露了?
最后,根据我研究的各种文档,实际实例化 EventArgs
的时间有两个主要差异。哪个被认为是 "more" 正确的?:
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
class 没有任何变量或属性,因此每次都创建一个新实例没有意义。在你的情况下,因为你有一个默认值,所以有两个 'empty' 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
的定义。 - 我已经实现了事件处理程序的线程安全版本(您的代码中的第二个示例)。如果订阅事件的事件处理程序列表发生变化,则您的第一个示例不安全。你的第二个是,因此你应该选择那个。
关于你的最后一点:这取决于你是否打算让调用委托更改对象(它是传递一个实例还是传递多个实例)。在您的情况下,由于无法更改实例,所以没关系。