关于事件的价值/参考类型的问题
在MSDN上,我发现以下内容:
public event EventHandler SampleEvent; public void DemoEvent(string val) { // Copy to a temporary variable to be thread-safe. EventHandler temp = SampleEvent;
是参考吗?
如果是这样,我不理解其含义,因为当SampleEvent变为null时,temp也是如此
if (temp != null) temp(this, new MyEventArgs(val)); }
这是与线程有关的偏执狂。 如果另一个线程在您将其检查为null
之后取消订阅最后一个处理程序,则它可能变为 null
并且您将导致exception。 由于委托是不可变的,因此将委托的快照捕获到变量中会阻止这种情况发生。
当然,它确实有另一个副作用,你可以(而不是)最终提高事件对一个认为已经取消订阅的对象…
但要强调 – 当多个线程订阅/取消订阅对象时,这只是一个问题,这是:罕见,而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代码需要注意的另一个重要特性是event
关键字的CIL等价物保留在CIL中。 换句话说,事件是CIL代码明确识别的事物; 它不仅仅是一个C#构造。 通过在CIL代码中保留等效event
关键字,所有语言和编辑者都能够提供特殊function,因为他们可以将事件识别为特殊的类成员。
我猜你很困惑,主要是因为你认为事件是一个类的糖语法,对吧?
上述就是C#学习教程:关于事件的价值/参考类型的问题分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1009109.html