Question regarding to value/reference type of events

百般思念 提交于 2019-11-29 09:32:10

This is a paranoia thing to do with threading. If another thread unsubscribes the last handler just after you've checked it for null, it could become null and you'll cause an exception. Since delegates are immutable, capturing a snapshot of the delegate into a variable stops this from happening.

Of course, it does have the other side effect that you could (instead) end up raising the event against an object that thinks it already unsubscribed...

But to stress - this is only an issue when multiple threads are subscribing / unsubscribing to the object, which is a: rare, and b: not exactly desirable.

(From what I read in Essential C# 4.0)

Basically, from this C# code:

public class CustomEventArgs: EventArgs {…}
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
public event CustomEventHandler RaiseCustomEvent;

the compiler will generate CIL code (loosely) equivalent to the following C# code:

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) }
}

When you copy the event, you actually copy the private CustomEventHandler customEventHandler. Since delegate is immutable, the copy won't be affected when the original customEventHandler is modified. You can try this code to see what I mean:

string s1 = "old"; 
string s2 = s1; 
s1 = "new"; // s2 is still "old"

Another important characteristic to note about the generated CIL code is that the CIL equivalent of the event keyword remains in the CIL. In other words, an event is something that the CIL code recognizes explicitly; it is not just a C# construct. By keeping an equivalent event keyword in the CIL code, all languages and editors are able to provide special functionality because they can recognize the event as a special class member.

I guess you were confused mainly because you thought event is a sugar-syntax for a class, right?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!