在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));
}
这是与线程有关的偏执狂。如果 另一个 thread取消订阅最后一个处理程序 刚过 你已经检查过了 null
, 它可以 成为 null
你会引发异常由于委托是不可变的,因此将委托的快照捕获到变量中会阻止这种情况发生。
当然,它确实有 其他 副作用,你可以(而不是)最终提高事件对一个认为已经取消订阅的对象...
但要强调 - 当多个线程订阅/取消订阅对象时,这只是一个问题,这是:罕见,而b:不完全合乎需要。
这是与线程有关的偏执狂。如果 另一个 thread取消订阅最后一个处理程序 刚过 你已经检查过了 null
, 它可以 成为 null
你会引发异常由于委托是不可变的,因此将委托的快照捕获到变量中会阻止这种情况发生。
当然,它确实有 其他 副作用,你可以(而不是)最终提高事件对一个认为已经取消订阅的对象...
但要强调 - 当多个线程订阅/取消订阅对象时,这只是一个问题,这是:罕见,而b:不完全合乎需要。
(从我在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的另一个重要特征
代码就是CIL相当于的 event
关键字仍保留在CIL中。
换句话说,事件是CIL代码识别的事物
明确;它不仅仅是一个C#构造。通过保持等价物 event
CIL代码中的关键字,所有语言和编辑都能够提供
特殊功能,因为他们可以将事件识别为特殊事件
班级成员。
我猜你很困惑,主要是因为你认为事件是一个类的糖语法,对吧?