我知道以下两种方法都有效,但我想知道在性能/维护/其他方面是否更好。
简短的方法:
public event EventHandler MyEvent;
漫长的道路:
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add { _myEvent += value; }
remove { _myEvent -= value; }
}
漫长的方式似乎与封装具有属性的成员类似,这确实是一种很好的做法。但这是否适用于事件处理程序?
答案 0 :(得分:28)
在这种情况下,"良好实践的论点"有点琐事;第一个是"字段式的事件&#34 ;;你注意到:
漫长的方式似乎与使用属性
封装成员类似
但是:这是封装的(在add
/ remove
后面);因此,与属性相比,它实际上是区别:
public int Foo {get;set;}
和
private int foo;
public int Foo {
get { return foo; }
set { foo = value; }
}
在这种情况下,我会说"使用第一个,除非你有实际的理由不去" - 它仍然隐藏在访问者后面。此外,值得注意的是,您的第二个示例是不类似字段的事件(第一个示例)扩展到的内容:编译器将线程安全性添加到组合中。所以:我会说使用第一个样本:
public event EventHandler MyEvent;
请注意"如何"对于线程安全性取决于您使用的编译器版本(实际上,哪个规范)。在最近的Microsoft C#编译器中,它使用Interlocked
操作(CompareExchange
等)执行此操作,因此它不需要专用的专用同步对象。
答案 1 :(得分:5)
第一种方式与创建名为EventHandler
的私有MyEvent
完全相同。当它在类中被访问时,在类(myClassInstance.MyEvent += SomeHandler
/ myClassInstance.MyEvent -= SomeHandler
)Add
/ Remove
之外调用时,会返回事件处理程序(即调用委托没有问题)分别叫。这些方法与你用第二种方式编写的方法相同(除了它们增加了线程安全性)。
那你为什么要在实际不需要的时候编写更多代码?
答案 2 :(得分:1)
要检查Marc Gravel的意思,我尝试了以下代码:
public event EventHandler MyEventShortWay;
private EventHandler _myEvent;
public event EventHandler MyEventLongWay
{
add { _myEvent += value; }
remove { _myEvent -= value; }
}
我对生成的内容感到惊讶(我编辑了反编译的变量名称):
private EventHandler _myEventShortWay;
public event EventHandler MyEventShortWay
{
add
{
EventHandler handler2;
EventHandler myEventShortWay = this._myEventShortWay;
do
{
handler2 = myEventShortWay;
EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value);
myEventShortWay = Interlocked.CompareExchange<EventHandler>(ref this._myEventShortWay, handler3, handler2);
}
while (myEventShortWay != handler2);
}
remove
{
EventHandler handler2;
EventHandler myEventShortWay = this._myEventShortWay;
do
{
handler2 = myEventShortWay;
EventHandler handler3 = (EventHandler)Delegate.Remove(handler2, value);
myEventShortWay = Interlocked.CompareExchange<EventHandler>(ref this._myEventShortWay, handler3, handler2);
}
while (myEventShortWay != handler2);
}
}
private EventHandler _myEvent;
public event EventHandler MyEventLongWay
{
add
{
this._myEvent = (EventHandler) Delegate.Combine(this._myEvent, value);
}
remove
{
this._myEvent = (EventHandler)Delegate.Remove(this._myEvent, value);
}
}