class MyClass { public event EventHandler MyEvent; public void F() { EventHandler handler = MyEvent; if(handler != null) handler(this,EventArgs.Empty); } }
而不是这样做的错误方式,容易出现这种竞争状况:
class MyClass { public event EventHandler MyEvent; public void F() { if(MyEvent != null) MyEvent(this,EventArgs.Empty); } }
我的问题是,鉴于System.Delegate是一个引用类型:如果MyEvent不为null,那怎么来了
EventHandler handler = MyEvent;
我希望将MyEvent委托分配给’handler’变量,那么一旦有人改变了MyEvent,那么’handler’引用的对象也会被改变.
显然,情况并非如此,否则这个漂亮的小样式将不起作用.
我已经研究了.NET源代码,但仍然找不到我的答案(可能在那里,但是我已经找了一个小时,找不到它,所以我在这里)
我也看过C#语言规范对事件和代表的看法,但是并没有解决这个问题.
谢谢你的时间.
解决方法
I would expect that once I got the
MyEvent delegate inside the ‘handler’
reference,once somebody would change
MyEvent that the object that ‘handler’
references will be changed as well.
[..]
Notice that System.Delegate is a class and not a struct.
尽管委托类型是引用类型是正确的,但它们是不可变的引用类型.从System.Delegate
:
“Delegates are immutable; once
created,the invocation list of a
delegate does not change.[…]
Combining operations,such as Combine
and Remove,do not alter existing
delegates. Instead,such an
operation returns a new delegate that
contains the results of the operation,
an unchanged delegate,or Nothing.
另一方面,这种模式解决的唯一问题是阻止尝试调用一个空委托引用.事件是prone to races,尽管这个“修复”.