开发者

Question regarding to value/reference type of events

On the MSDN, I have found following:

public event EventHandler<MyEventArgs> SampleEvent;

public void DemoEvent(string val)
{
// Copy to a temporary variable to be thread-safe.
    EventHandler&开发者_StackOverflowlt;MyEventArgs> temp = SampleEvent; 

Is it reference?

If so I do not understand its meaning as when SampleEvent became null, so does the temp

    if (temp != null)
        temp(this, new MyEventArgs(val));
}


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜