In some ASP.NET examples i see that events are used with delegates like this and sometimes without them like this.
Please explain!
All events are delegate types (they all inherit from EventHandler that inherits from MulticastDelegate which interits from Delegate). Sometimes (or I would rather say most of the time) there is no need to declare your own custom delegate for an event though. You can use existing delegates as long as they match the signature of your event. With the introduction of EventHandler<T> in .NET Framework 2.0, the need for custom event delegates pretty much disappeared (as long as you follow the event design of the framework). So, doing the following:
// declare an event with a custom delegate type
public delegate void MyCustomEventHandler(object sender, EventArgs e);
public event MyCustomEventHandler SomeCustomEvent;
...is equivalent of this:
// declare an event with an existing delegate type
public event EventHandler SomeCustomEvent;
Should you have some custom EventArgs class, you can instead use the generic EventHandler<T> for your events:
class MyCustomEventArgs : EventArgs
{
// you custom stuff here
}
public event EventHandler<MyCustomEventArgs> SomeCustomEvent;
You don't need to specify a delegate if you're subscribing to an event created by someone else (your asp.net Page or some asp.net web control). Just provide a method that matches the delegate's signature.
The person who creates the event must provide the delegate. The subscriber just provides the method.
ASP.NET adds to the confusion as it will "wire up" events for you during compilation if you specify AutoEventWireup="true" within your page's definition.
Events in .NET are implemented with delegates.
From the page of your first link:
An event enables objects in a class to
notify other objects that something
has happened that they should perhaps
react to. Events in [.NET] are based
on a publisher-subscriber model. The
class that implements an event is
called the publisher of that event. A
subscriber class can subscribe to a
published event by registering an
appropriate event handler with the
published event.
...
The Delegate type determines the
signature of the event handlers that
can be registered with an event.
So the publishing class defines a delegate that the subscribing classes must implement. When the event is raised the subscribing class's methods are invoked through the delegate. And a method that handles an event is called an event handler. Events are properties of the class publishing the event. The keyword event is designed to maintain the publish/subscribe idiom.
Related
I've been recently learning 'events' and 'delegates' in C#.
Now I have a question that I didn't find the answer to, anywhere else.
As we all know every event is created based on a specific delegate. At first I thought that events are like delegate instances, but then I figured out that they are not.
My question here is that what is the relation between an event and its base delegate? does that event create an instance of the delegate and assign the 'event handler' methods to that at the runtime? or the assigned delegate is just a convention for assigning 'event handlers'?
An event is basically a list of methods to be invoked. Thus, delegate is nothing but kind of "strongly-typed" method reference. That is why there are exactly 2 possible operations on events: add handler += and remove handler: -=. That should prevent mistakes like accidental .Clear(), which will unsubscribe all existing listeners momentarily.
If you need more "obvious" example of how it works, than let the List<Delegate> be an event, where Delegate represents reference to a whatever function of a certain signature. Whenever you need to "invoke" event, you loop over existing list of delegates and simply invoke each one with the same parameter.
An event for a delegate is the same as aan auto-property for a backing-field. As an auto-property is just a wrapper around a backing-field an event is just a wrapper around a (backing) delegate. It provides an add- and a remove-method to append or remove event-handlers. So you have a private list of handlers and the event is just a wrapper to expose this list to the outside.
You can define an event as follows:
private EventHandler _explicitEvent;
public event EventHandler ExplicitEvent
{
add { _explicitEvent += value; }
remove { _explicitEvent -= value; }
}
So you have a private backing-field, which is a delegate. You can surely assign multiple handlers to the same delegate and thus to the event. In fact when you have an event as this:
public event EventHandler MyEvent;
the compiler will implicitely create the private backing-delegate for you, as it does for auto-properties also.
As for properties you can add some further logic within the add- and -remove-accessors in order to modify what happens when assigining an handler. You could make some validations for example or call some logging.
According to Microsoft Docs => Here
An event is a special kind of multicast delegate that can only be invoked from within the class that it is declared in. Client code subscribes to the event by providing a reference to a method that should be invoked when the event is fired. These methods are added to the delegate's invocation list through event accessors.
So, the answer would be: Yes. Events are basically a special type of multicast delegate.
Button.Click += new RoutedEventHandler(_click);
private void _click(object sender EventArgs e)
{
//...
}
In the code above, we're instantiating the RoutedEventHandler type, which is a delegate, with the Button.Click event. But the event is an abstracted delegate by itself, isn't it? I don't understand the difference between this and just instantiating the RoutedEventHandler to a variable, and then adding variables to the instance's invocation list. Am I making this too hard? How do all of the delegates involved here work?
Edit: so my main concern is just trying to bridge the gap between what I know about delegates and what I know about events. I know an event is a delegate wrapped in another layer of abstraction. So when you assign another delegate to its invocation list using the += operator, you're just assigning a delegate to another delegate, correct? But in the code I wrote above, you're not actually instantiating the RoutedEventHandler class, so I'm confused about how you're actually passing it into the invocation list of the Button.Click event. I also get confused because it seems like everything is actually pointing to something else with delegates and events, and the references get complicated.
Probably this answer will help you.He has explained it in good detail:-
Events
You can think of events as wrappers to a collection of delegates (with some syntactic sugar for adding / removing members). Events deal with multicasting the call to multiple delegates, you can add custom logic to allow (or not) a delegate to be added (the same way you can wrap a field in a property and add some logic on the getter / setter for the property). Having an event in a class "advertises" to the world that they can safely add handlers (which are implemented as delegates) to receive said events - and that allows for things such as design-time integration with IDEs such as Visual Studio.
When you use a delegate in the context of an event the compiler will generate both a provide backing field for the delegate and a add/remove public property for subscribers to attach to the event. You could just use the delegate as an event as you describe however you will not be able to limit the subscribers to just += and -=
private EventHandler _backingDelegate;
public event EventHandler Click {
add {
_backingDelegate += value;
}
remove {
_backingDelegate -= value;
}
}
I would like to know:
Subscriber is a name for class that subscribes for the event or also for the method that is handling the event? I mean, does it make sense to say "subscribe method to event"?
On MSDN it says that event delegate should have exactly 2 arguments. Not sure what it means as I often create events with my custom delegate that has e.g. none or one argument.
1) Yes, it definitely makes sense to talk about subscribing a method to an event. You can actually think of there being three entities involved:
The subscribing code which is actually performing the subscription itself
The event publisher
The handler which is being subscribed; this is often - but not always - code in the same class as the subscribing code
2) You certainly can create events using delegates with any number of parameters. The convention is that delegates used in events have two parameters: a "sender" and an "argument" derived from EventArgs. For example, this means that you can subscribe a handler from a method with a signature of void Foo(object sender, EventArgs e) to any event following the convention.
A subscriber is a method that is added as an event handler.
Standard practice is to use the EventHandler<T> delegate for events; this has two arguments.
However, you can create your own events with any number of arguments.
I'll concentrate on the second point. As Jon pointed out, you can use your own delegates for events. But you rarely should. Even if you don't care about conventions, look at it this way: whenever you use your own events with custom delegates, you have the following code besides the event field itself:
Your custom delegate
Event handlers (methods with matching signature) - sometimes a lot of them
Event invocation points (where you need to pass all the parameters)- sometimes a lot of them
I also tend to create the InvokeMyEvent methods that do the nullity checking and other stuff that needs to be done
You have to change all of these if you decide to add or remove a parameter or change a parameter type.
Now, if you create your own class that inherits EventArgs or use the EventArgs<T>, you have:
Your CustomEventArgs class
Event handlers
Event invocation points
InvokeMyEvent methods.
Whenever you decide to change the event args you have to change only your custom args class and some of the event invocation points. "Some", because you can provide suitable default values for fields of your args class and only provide the values when you need it.
Most of good/bad practice talks are focused on one thing - ease of change. Changes always happen. The fewer things you have to alter when they do, the better. Design has a lot of iterations and the odds are that you'll have to change your interfaces and types a lot. You don't want to change tens of signatures whenever you decide that you don't need the parameter anymore. So use the EventArgs or EventArgs<T> and save yourself some headache.
Another minor point is that you'll probably want to declare some methods that take care of raising the events, like this:
public static public void FireEvent<T>(this EventHandler handler, object sender, EventArgs<T> e)
where T : EventArgs
{
if (handler != null)
handler(sender, e);
}
If all your events are EventHandler-based, you can use one all-purpose method for things like that. If not, then you'll eventually have tens of them.
Possible Duplicate:
What is the difference between a delegate and events?
Possible Duplicate:
Difference between events and delegates and its respective applications
(copied from this duplicate)
When i have to raise an event i do this
public delegate void LogUserActivity(Guid orderGUID);
public event LogUserActivity ActivityLog;
even this works
public delegate void LogUserActivity(Guid orderGUID);
public LogUserActivity ActivityLog;
What is the difference between two of them
There are three things here:
Declaring a delegate type
Creating a public variable of a delegate type
Creating a public event of a delegate type
The variable is just a normal variable - anyone can read from it, assign to it etc. An event only exposes subscribe/unsubscribe abilities to the outside world. A field-like event as you've shown here effectively has a "default" subscribe/unsubscribe behaviour, stored in a field with the same name. Within the declaring class, you access the field; outside you access the event.
I have an article about events and delegates which explains in more detail.
EDIT: To answer the comment, you can easily initialize a field-like event with a "no-op" handler:
public event LogUserActivity ActivityLog = delegate{};
Events and public delegates differ in one big way that keeps me from using public delegates in most cases:
Event:
obj.ActivityLog = null; // invalid
Public Delegate:
obj.ActivityLog = null; // valid
This matters, because I only want the subscriber to add/remove themselves from the list in most cases. I don't want other objects unhooking events from other subscribers.
In cases where the delegate is less of an event and more of a callback, I tend to use public methods to do this and keep the public delegate from being exposed directly:
obj.RegisterActivityCallback(...)
An event is an abstraction over a delegate, just as a property is an abstraction over a field. And - just like a property - an event allows you to gain fine control over what happens when a handler is added/removed:
public event LogUserActivity ActivityLog
{
add { ... }
remove { ... }
}
Indeed, your event may not have a delegate backing it at all, just like a property may not necessarily have a field backing it.
In the first case you can assign multiple listeners to your ActivityLog event as in:
logger.ActivityLog += new LogUserActivity(Listener1);
logger.ActivityLog += new LogUserActivity(Listener2);
Both methods (Listener1 and Listener2) will be called when the event is fired. In the second case you are not creating an event but a delegate. In this case you can only assign one listener:
logger.ActivityLog = new LogUserActivity(Listener1);
In this case you do not fire an event but instead you call the delegate. An event is really just a chain of delegates that are called in turn.
to add to all the previous answers, An event IS a delegate, of a specific type. A delegate is a type that is designed to act as a "smart" function pointer, or, putting it another way, as a smart "wrapper" for a function pointer, that allows the compiler to intelligently decide at compile time whether the function(s) you are sticking into the delegate are consistent with the uses you are making of the delegate (consistency is based on the function signature).
An event is a delegate with a specific signature, specifically, one that does not return anything (returns void), and takes two parameters, a System.object, to hold a reference to whatever object triggered the event, and an instance of some type derived from System.EventArgs, to hold whatever other data the event needs to carry with it from the initialtor to the handler.
I've been trying to learn about events/delegates, but am confused about the relationship between the two. I know that delegates allow you to invoke different functions without needing to know what particular function is being invoked. (eg: a graphing function needs to accept inputs that are different functions to be graphed).
But I don't see how delegates are used in Events.
Can someone construct a simple example (in pseudocode or C# or Java) that illustrates the workings of Delegates as related to Events?
Thanks!
(This is all from a C# perspective.)
I have an article about the differences between events and delegates. That covers everything mentioned below in a lot more detail.
Basically I like to think of an event as being like a property - it's a pair of methods, that's all. Instead of get/set, an event has add/remove - meaning "add this event handler" and "remove this event handler". At the core, that's all an event is.
C# also has field-like events which are a shortcut:
public event EventHandler Foo;
declares both a field and an event, with a nearly trivial add/remove implementation. Within the class, referring to Foo refers to the field. Outside the class, referring to Foo refers to the event.
The basic idea is that an event allows other code to subscribe to and unsubscribe from it, by passing in a delegate (the event handler). Usually, subscription is implemented by creating a new multicast delegate containing the previous list of event handlers and the new one. So if you're storing the event handlers in a field called myEventHandlers, the subscription implementation might be:
myEventHandlers += value;
Similarly unsubscription usually involves creating a new multicast delegate without the specified handler:
myEventHandlers -= value;
Then when you want to raise/fire the event, you just call that multicast delegate - usually with a nullity check to avoid an exception being thrown if no-one has subscribed:
EventHandler handler = myEventHandlers;
if (handler != null)
{
// You could pass in a different "sender" and "args" of course
handler(this, EventArgs.Empty);
}
Using events, the subscribers don't know about each other, and can't raise the event themselves (usually). In other words, it's a pattern of encapsulation, which has been given status within both the language and the platform.
You'll need to be specific as to which language you want. As far as I know, Java doesn't have a concept of delegates (though I could be completely wrong); it tends to follow an observer pattern for event handling.
C#, however, does. An event in C# has the same relation to a delegate as a property has to its backing field. The delegate itself is what stores the pointer to the function that handles the event (or, more accurately, the list of pointers attached to the event; I use the term "pointer" loosely here).
If I declare this in C#:
public event EventHandler MyEvent;
And call the event like this:
MyEvent(this, EventArgs.Empty);
It's really just some shorthand for a full event implementation:
private EventHandler myEventHandler;
public event EventHandler MyEvent
{
add { myEventHandler += value; }
remove { myEventHandler -= value; }
}
And calling it...
myEventHandler(this, EventArgs.Empty);
All this is to say that an actual event exposes two operations: add and remove that are used by the consuming code to attach their event handlers to the event. In the default (shorthand) notation, the compiler creates a private instance member of the delegate type and uses it in the way that I described above. When you "invoke" the event, the compiler actually substitutes the name of the event for the name of the private backing delegate it created. This is why you can't invoke an event from a subclass--if the event is created in shorthand, then the backing member is private.
Difference is simple.
delegate is a class with two fields - object and MethodInfo.
event is a private field of type delegate and two public methods add and remove.
Usually under the hood of event MulticastDelegate is used - it's a class inherited from Delegate and containing list of Delegates. This allows event to have multiple subscribers.
You can look at:
http://msdn.microsoft.com/en-us/library/17sde2xt.aspx
The example is continued here:
http://msdn.microsoft.com/en-us/library/xwbwks95.aspx
Basically, as was mentioned, events are just special cases of delegates, but with the changes in .NET 3.5 you can write events without using delegates, though under the hood delegates are still written.
If you look at this article, they show how to use lambda expressions and anonymous functions for events:
http://msdn.microsoft.com/en-us/library/ms366768.aspx
.Net events are just delegates under the hood: They provide some syntactic sugar in the compiler.
You can set/reset a delegate, but you can only add or remove an event handler. The rationale is that you won't care who else subscribes to an event whereas plain delegates are more used in a "callback" scenario.
But at the end of all things they are very very similar.
Some resources:
C# events vs. delegates
Delegates & Events - A short Q&A
I'm new to the java world but I have to admit I'm pretty delighted, but I still miss some C # stuff, so design this pattern that has given me good results, Java experts see some drawback in using this pattern? It only supports java 8:
#FunctionalInterface
public interface IEvent<TEventArgs extends Object> {
void invoke(TEventArgs eventArgs);
}
public class EventHandler<TEventArgs>
{
private ArrayList<IEvent<TEventArgs>> eventDelegateArray = new ArrayList<>();
public void subscribe(IEvent<TEventArgs> methodReference)
{
eventDelegateArray.add(methodReference);
}
public void unSubscribe(IEvent<TEventArgs> methodReference)
{
eventDelegateArray.remove(methodReference);
}
public void invoke(TEventArgs eventArgs)
{
if (eventDelegateArray.size()>0)
eventDelegateArray.forEach(p -> p.invoke(eventArgs));
}
}
public class DummyEventProducer
{
// The event
public EventHandler<String> myEvent = new EventHandler<>();
public void onMyEvent(String A)
{
myEvent.invoke(A);
}
}
public class DummySubscriber {
// The method will be subscribed to the event
public void methodCallWhenEventGetTriggered(String eventArgs)
{
System.out.println("event fired with eventargs: " + eventArgs);
}
}
public class Main {
public static void main(String[] args)
{
// A dummy producer
DummyEventProducer producer = new DummyEventProducer();
// A dummy subscribers
DummySubscriber testingInstanceA = new DummySubscriber();
DummySubscriber testingInstanceB = new DummySubscriber();
DummySubscriber testingInstanceC = new DummySubscriber();
// We create decoupled event links because we want to un-subscribe later
IEvent<String> EventSink1 = testingInstanceA::methodCallWhenEventGetTriggered;
IEvent<String> EventSink2 = testingInstanceB::methodCallWhenEventGetTriggered;
IEvent<String> EventSink3 = testingInstanceC::methodCallWhenEventGetTriggered;
// subscribe to the event on dummy producer
producer.myEvent.subscribe(EventSink1);
producer.myEvent.subscribe(EventSink2);
producer.myEvent.subscribe(EventSink3);
// fire the event on producer
producer.onMyEvent("Hola MUNDO with decoupled subscriptions!");
// unsubscribe to the event on dummy producer
producer.myEvent.unSubscribe(EventSink1);
producer.myEvent.unSubscribe(EventSink2);
producer.myEvent.unSubscribe(EventSink3);
// fire the event on producer again
producer.onMyEvent("Hola MUNDO! with no events subscriptions :(");
// IF YOU DON CARE ABOUT UNSUBSCRIBE YOU CAN LINK EVENTS DIRECTLY TO THE SUBSCRIBER
producer.myEvent.subscribe(testingInstanceA::methodCallWhenEventGetTriggered);
producer.myEvent.subscribe(testingInstanceB::methodCallWhenEventGetTriggered);
producer.myEvent.subscribe(testingInstanceC::methodCallWhenEventGetTriggered);
// fire the event on producer again
producer.onMyEvent("Hola MUNDO! with strong link subscriptions (cannot be un-subscribed");
}
}
Feel free to ask, corrections, suggestions =)
Best regards!