In answer to my other question How to send custom event message just after control instantiation? I read this:
if (ValueChanged != null)
{
ValueChanged(sender, e);
}
What is ValueChanged in the first case ? Not a function as in the second instruction ? How can the same symbol be used for both ... and function ?
uPDATE after james's answer: if ValueChanged is an Object, How can I call it as if it were a Method? Is it a syntactic sugar or alien syntax with some mysterious mechanism behind like calling ValueChanged.Invoke(sender, e); ?
ValueChanged is a multi-cast delegate, which is an object. If no one has subscribed to the event, it can be null, hence the check. If you want to avoid the check, you can define an empty delegate and assign it to the event.
public event EventHandler ValueChanged = delegate {};
You can now just call ValueChanged(sender, e) because ValueChanged can never be null.
Like many things in C# there are language features designed to make things easier. Think of ValueChanged as a field and that you check that it is null (internally the delegate will check for subscribers) and the second a shorthand version of
ValueChanged.Invoke(sender, e);
The actual signature of the event is more than a field of course. It exposes a public add/remove property for subscribers as well as a private field for invoking.
ValueChanged is the same in both cases.
First, you check if it is null, which will be the case if there are no subscribers.
Second, you execute the delegate using method-like syntax.
Events are just delegates - a reference to a function elsewhere. When invoking an event like above, we are calling the delegate. Since the delegate is just a reference to a function, we need to handle the case where it may not have been set previously (I.E. null)
ValueChanged is a reference to one or more functions. If there are no references, then the value will be null. If the value is not null, then all of the referenced functions will called by the ValueChanged(sender, e); syntax.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a downside to adding an anonymous empty delegate on event declaration?
The following pattern is quite common when using event handlers (in C#):
public event Action handler;
…
// some method:
if(handler != null) handler();
Are there any downsides of assigning an empty delegate to this event? This would save the if !=null condition everywhere, where the event is fired. Of course, this only applies, when the we cannot guarantee that the event is always assigned a proper delegate.
public event Action handler;
…
// in constructor:
handler += ()=>{};
…
// some method:
handler();
Sure, there's a slight performance hit, but it makes the code much cleaner. What's the best practice in such a case? Any technical disadvantages?
Interesting idea, I've never thought of doing that. The way i do my custom events is i make a OnCustomEventName taking parameters for the event and just do the check in there for null. and call OnCustomEventName from the code wherever i want the event triggered from.
Avoids any performance hits and keeps the operational code cleaner than a 2-line if check every time you want the event fired.
That being said this isn't answering the question about technical disadvantages but more of a best practice when firing events.
example code for threadsafe "On" function.
private void OnCustomEventName()
{
DelegateName localhandler = CustomEventName;
if (localhandler != null)
localhandler();
}
Instead of adding an empty delegate in the constructor, you can wrap the handler in a function which first checks if the handler is null then calls it. The downside of this is if you have a lot of events, you will have a lot of functions that wrap each event.
private void HandlerWrapper()
{
Action localHandler = handler;
if (localHandler != null) handler();
}
I haven't really found any big downsides to do this and generally I prefer it over checking for null. The only issue I cant think of is that it might lead to annoying steps in the code when debugging (i.e.
having to step over the empty delegate whenever stepping into an event).
I think that performance isn't an issue - if application performance degenerates significantly by invoking events, the event should probably not have been there in the first place.
public class TestA
{
public event Action<int> updateEvent;
...
if(updateEvent != null)
{
Actin<int> tempEvent = updateEvent;
updateEvent(1);
}
}
public class TestB
{
public Action<int> updateEvent;
...
if(updateEvent != null)
{
Actin<int> tempEvent = updateEvent;
updateEvent(1);
}
}
however event Action<T> is eventQueue au
use same and resutl same. What is more good? (i like TestB. Because simple using.)
The event modifier is useful to prevent an assignment. What does it mean? If that's a callback with many handlers attached you may want to prevent that someone simply write:
myObject.UpdateEvent = null or something like that. With event they can't do that. Take a look at Learning C# 3.0: Master the fundamentals of C# 3.0.
The code you use to call the event isn't bad but not so useful, if you assign the delegate to temporary variable you may want to be somehow thread-safe (someone could unhook after your null check) so you should do it before the check:
Action<int> tempEvent = updateEvent;
if (tempEvent != null)
tempEvent(1);
A little side note: if you use events you may want to follow .NET Framework patterns and guidelines, take a look at MSDN
To the compiler, the difference is that the event cannot be invoked except by the declaring class (like a private member). You can use either in the same way.
To design, events should represent their namesake, i.e. events. Think of a Delegate as just the type or signature of methods. You would declare a class to have an event (of type Action), and you would add (subscribe) to that event other Actions (or methods that can be cast to an Action).
Furthermore, it is common practice to create events of a type that inherits from EventHandler<T>
An event is just a delegate with some access wrappers.
The problem with your TestB is that because the updateEvent delegate is public, ANYONE can fire the delegate, not just the class owning it.
Defining it as an Event as in your TestA, client code can only subscribe or unsubscribe to the event, they cannot fire it.
ps. You do not need your tempEvent delegates.
public delegate void SecondChangedHandler(
object clock,
TimeInfoEventArgs timeInformation);
public event SecondChangedHandler SecondChanged;
I have written a clock based on this article.
Now if i remove the event keyword i get the same result, so what does event really do?
It's compiled differently. It makes it so someone can't do
mySecondChangedHandler.SecondChanged = SomeMethod(...); //overwrite
mySecondChangedHandler.SecondChanged(...); //invoke
but only
mySecondChangedHandler.SecondChanged += SomeMethod(...);
mySecondChangedHandler.SecondChanged -= SomeMethod(...);
The event keyword creates a private delegate field, and a pair of public event accessors called add_EventName and remove_EventName. (details)
This means that writing EventName inside the class returns the delegate instance, allowing you to call or inspect the event handlers.
Outside the class, EventName doesn't really exist; all you can do is write EventName += something and EventName -= something, and the compiler will convert it into calls to the accessors. (like a property)
For more details, see this series of blog posts.
The event keyword does two things
It supplied permissions. Only the class can raise the event, however any external method can invoke the raw delegate
It provides metadata which can be used for designers and the like
The event keywords means only methods on the instance that hosts the SecondChanged field can invoke it. External attempts will fail.
The event keyword creates a pair of accessors for a delegate. These are effectively two methods (add and remove) that are called when you subscribe or unsubscribe from the event.
In your case, you're creating a "field-like event". The compiler makes a delegate behind the scenes, and allows you to subscribe and unsubscribe from it's invocation list. This means that you have all of the functionality of a delegate, but you're restricting access so that that outside world can "handle" the event, but not raise the event (invoke the delegate).
You can, however, also explicitly create your own accessors for an event, and these can do other things (though that's not typically recommended unless there is a good reason to do so).
Quote from C# lang reference about keyword event,
Events are a special kind of multicast delegate that can only be invoked from within the class or struct where they are declared (the publisher class).
I've just encountered a bug in the program I'm writing where an exception was thrown stating an "object reference must be set to an instance of an object". Upon investigation, I found that this exception was thrown when trying to fire an event BUT the event didn't have any delegate methods added to it.
I wanted to check that my understanding was correct that as a developer you shouldn't fire events without first checking that the event doesn't equal null? For example:
if (this.MyEventThatIWantToFire != null)
{
this.MyEventThatIWantToFire();
}
Thanks in advance for the advice/thoughts.
The pattern you've shown is broken in a multi-threaded environment. MyEventThatIWantToFire could become null after the test but before the invocation. Here's a safer approach:
EventHandler handler = MyEventThatIWantToFire;
if (handler != null)
{
handler(...);
}
Note that unless you use some sort of memory barrier, there's no guarantee you'll see the latest set of subscribers, even ignoring the obvious race condition.
But yes, unless you know that it will be non-null, you need to perform a check or use a helper method to do the check for you.
One way of making sure there's always a subscriber is to add a no-op subscriber yourself, e.g.
public event EventHandler MyEventThatIWantToFire = delegate {};
Of course, events don't have to be implemented with simple delegate fields. For example, you could have an event backed by a List<EventHandler> instead, using an empty list to start with. That would be quite unusual though.
An event itself is never null, because the event itself is just a pair of methods (add/remove). See my article about events and delegates for more details.
You shouldn't do it that way - if someone where to remove a listener between the if and the call to the event, you'd get an exception. It is good practise to use it with a local variable:
protected void RaiseEvent()
{
var handler = Event;
if(handler != null)
handler(this, EventArgs.Empty);
}
Of course, this has the disadvantage of maybe calling a listener that already was removed between the creation of the local variable and the call to the handler.
Yes, you should check it for null but the way you're doing it leads to a race condition. It's possible the event may end up being null anyway if someone unsubscribes the last delegate in between your "if" and your event raise. The accepted way to do this is like:
var temp = this.MyEventThatIWantToFire;
if (temp != null) {
this.temp(this, EventArgs.Empty);
}
or alternatively, ensure there's always at least one delegate in the invocation list by declaring your event like this:
public event EventHandler MyEventThatIWantToFire = delegate {};
Make sense?
Yes, your understanding is correct. It's up to you to check the delegate's value before calling it.
Most delegates - which events are - are "multi-cast" delegates. This means that a delegate can manage a list of one or more methods that it will call when activated.
When the delegate evaluates to a null value, there are no registered methods; therefore, there is nothing to call. If it evaluates to something other than a null value, there is at least one method registered. Calling the delegate is an instruction to call all methods it has registered. The methods are called in no guaranteed order.
Using the addition-assignment operator (+=) or addition operator (+) adds a method to the delegate's list of methods. Using the subtraction-assignment operator (-=) or subtraction operator (-) removes a method from the delegate's list of methods.
Also note that the called methods are executed from the caller's thread. This is important if you are using events to update your user interface controls. In this situation, use of your control's InvokeRequired property lets you handle cross-threading calls (using Invoke() or BeginInvoke()) gracefully.
Yes in C# if an event has no delegates, it will be null, so you must check
Yes, you must check whether event is not null. Mostly you encounter protected method that does the check and invokes event, or even constructs event args. Something like this:
public event EventHandler Foo;
protected void OnFoo() {
if (Foo == null)
return;
Foo(this, new EventArgs());
}
This approach also alows your derived classes to invoke (or prevent invoking) the event.
I have an event Load
public delegate void OnLoad(int i);
public event OnLoad Load;
I subscribe to it with a method:
public void Go()
{
Load += (x) => { };
}
Is it possible to retrieve this method using reflection? How?
In this particular case you could, with reflection. However, in general, you can't. Events encapsulate the idea of subscribers subscribing and unsubscribing - and that's all. A subscriber isn't meant to find out what other subscribers there are.
A field-like event as you've just shown is simply backed by a field of the relevant delegate type, with autogenerated add/remove handlers which just use the field. However, there's nothing to say they have to be implemented like that. For example, an event can store its subscribers in an EventHandlerList, which is efficient if you have several events in a class and only a few of them are likely to be subscribed to.
Now I suppose you could try to find the body of the "add" handler, decompile it and work out how the event handlers are being stored, and fetch them that way... but please don't. You're creating a lot of work, just to break encapsulation. Just redesign your code so that you don't need to do this.
EDIT: I've been assuming that you're talking about getting the subscribers from outside the class declaring the event. If you're inside the class declaring the event, then it's easy, because you know how the event is being stored.
At that point, the problem goes from "fetching the subscribers of an event" to "fetching the individual delegates making up a multicast delegate" - and that's easy. As others have said, you can call Delegate.GetInvocationList to get an array of delegates... and then use the Delegate.Method property to get the method that that particular delegate targets.
Now, let's look again at your subscription code:
public void Go()
{
Load += (x) => { };
}
The method that's used to create the delegate here isn't Go... it's a method created by the C# compiler. It will have an "unspeakable name" (usually with angle brackets) so will look something like this:
[CompilerGenerated]
private static void <Go>b__0(int x)
{
}
Now, is that actually what you want to retrieve? Or were you really looking to find out which method performed the subscription, rather than which method was used as the subscribed handler?
If you call Load.GetInvocationList() you will be handed back an array of Delegate types. From the these types, you can access the MethodInfo.
You could use the GetInvocationList method which will give you all the subscribers.