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?
精彩评论