在MSDN上,我找到了以下内容:
public event EventHandler<MyEventArgs> SampleEvent;
public void DemoEvent(string val)
{
// Copy to a temporary variable to be thread-safe.
EventHandler<MyEventArgs> temp = SampleEvent;
是否参考?
如果是这样,我不理解其含义,因为当SampleEvent变为null时,temp
if (temp != null)
temp(this, new MyEventArgs(val));
}
答案 0 :(得分:12)
这是一个与线程有关的偏执狂。如果另一个线程取消订阅之后的最后一个处理程序,您已经检查了null
,那么可以成为 null
你会引发异常由于委托是不可变的,因此将委托的快照捕获到变量中会阻止这种情况发生。
当然,它确实有其他副作用,你可以(而不是)最终针对一个认为已经取消订阅的对象引发事件......
但要强调 - 当多个线程订阅/取消订阅对象时,这只是一个问题,这是:罕见,而b:不完全是理想的。
答案 1 :(得分:2)
(从我在Essential C#4.0中读到的内容)
基本上,从这个C#代码:
public class CustomEventArgs: EventArgs {…}
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
public event CustomEventHandler RaiseCustomEvent;
编译器将生成相当于以下C#代码的CIL代码(松散地):
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
private CustomEventHandler customEventHandler; // <-- generated by the compiler
public void add_CustomEventHandler(CustomEventHandler handler) {
System.Delegate.Combine(customEventHandler, handler);
}
public void remove_CustomEventHandler(CustomEventHandler handler) {
System.Delegate.Remove(customEventHandler, handler);
}
public event CustomEventHandler customEventHandler {
add { add_customEventHandler(value) }
remove { remove_customEventHandler(value) }
}
复制事件时,实际上是复制了private CustomEventHandler customEventHandler
。由于委托是不可变的,因此在修改原始customEventHandler
时不会影响副本。您可以尝试使用此代码查看我的意思:
string s1 = "old";
string s2 = s1;
s1 = "new"; // s2 is still "old"
关于生成的CIL的另一个重要特征
代码是event
关键字的CIL等价物保留在CIL中。
换句话说,事件是CIL代码识别的事物
明确;它不仅仅是一个C#构造。保持等效event
CIL代码中的关键字,所有语言和编辑都能够提供
特殊功能,因为他们可以将事件识别为特殊事件
班级成员。
我猜你很困惑主要是因为你认为事件是一个类的糖语法,对吗?