Reputation: 377
I read a lot of materials but I still did not understand, can someone explain me, please?
What do I know:
Declare an event:
public event MyEvent myEvent;
Vs.
declare EventHandler:
public EventHandler MyEventHandler;
While EventHandler is a keyword in .NET:
public delegate void EventHandler (Send object, EventArgs e);
So, EventHandler is a delegate and not an event, since it is not used in the keyword 'event'?
And when should I use 'Event' and when 'EventHandler'?
Upvotes: 15
Views: 16837
Reputation: 2978
Ah, the event vs. delegate question. I remember having that question as well...
So, suppose you're making a class called "Cat" and you want to let people know when your cat is hungry. You could do that in one of two ways: by exposing a delegate on the Cat class or by exposing an event.
You can think of a delegate as a pointer to a function (or method). So let's say there's a class called "Person" that has a method called FeedCat(Cat cat)
.
The delegate way
If your cat is exposing a delegate called HungryDelegate
, the person can point the delegate to their FeedCat
method, so that when the cat is hungry, it has a way to call the FeedCat
method on the person.
The problem here is, only one person can feed the cat. Suppose you want multiple people to be able to feed the cat. People can be busy doing other things, so it's important for the cat to be able to tell multiple people that it's hungry. That way, people get notified of this, and they can check up on the cat when they have a chance, see if someone already fed the cat, and feed it if not.
Events to the rescue:
An event is basically a list of delegates (of a certain type). If you expose a Hungry
event on your "Cat" class, multiple people can ADD pointers (delegates) to their FeedCat
methods.
They can also remove the pointers (delegates) to their FeedCat
methods if they like. Let's say a person moved out, and their sister is now taking care of the cat. The person can remove their delegate for their own FeedCat
function from the cat, so that they no longer get notified that the darn cat is hungry.
Events vs. multicast delegates?
Technically, in order to be able to provide multiple delegates, you could use the so called MultiCastDelegates instead of events. They are composite delegates (a linked list of delegates). The problem there is, everyone can mess with them from the outside. An evil person could remove everyone else's "FeedCat" delegates, and the poor cat would starve (or would have to learn to hunt).
The important thing when using events is that the person cannot see other people's delegates that are added to the event, and in principle it can't remove them or interact with them.
Upvotes: 23
Reputation: 39
This will be a long one but its the simplest explanation, the problem this is such a nuisance of a topic is because people are just using different words to explain the same thing
First of all, you should know a few things
also called :
to create a delegate you go
[[access modifier] delegate [return type] [delegate name]([parameters])]
example: public delegate int demo(int a);
now to execute all these methods stored in a list called delegate, you go
1. demo.invoke(a);
2. demo(a); ..... both are valid
using the dot and explicitly saying invoke shines in async programming where you use beginInvoke, but that is out of the scope of this topic
there is one more thing called "Creating an object of the delegate/instantiate Delegate" which is pretty much as it sounds but just to avoid confusion it goes like (for the above example )
example : demo del = new demo(); (or) Public demo del = null;
to add any method to the list called delegate you go += and you also need to remove it once the "requirements of the methods are met" you go -=
(requirements of the methods are met mean you no longer need the method to be active or aka "listening") if you don't remove it, it could cause a "memory leak" meaning your computers ram will be eaten alive, technically allocated memory will not be released
example: say there is a method
public int calculate (int c)
to add this method to delegate you go
1. del = calculate;
2. del += calculate; .... all are valid
to remove
del -= calculate
first of all notice the similarities between the delegate and the method, the return type(output) and the input/parameters are the same, and that is a rule you just cannot add any random or a bunch of methods in a delegate it needs to follow the input-output rule
now why are there 2 different ways to do one thing, the only thing different is the assignment operators (+, =), this introduces a new topic called
which is nothing but a constrained version of a Delegate, It's still a List of methods don't confuse when people explain these terminologies, they change the name, so stick with this to understand
what is the constraint? you cannot do this del = calculate;
what's the harm in it, say a bunch of methods are added to the Delegate(List), you do that 👆 all are wiped out and only a single method "calculate" remains, so to prevent that Events are used,
Event Syntax
Public Event demo del = null;
One more thing you cannot do with events is invoke the delegate directly like demo.invoke
since its public it can be accessed and invoked but with events, it can't
now you just add the methods to the event (a special type of delegate)
when to use an event vs a delegate, depends on your situation but pragmatically events are popular
few more keywords
MULTICASTING: nothing but adding more than one method to a delegate BROADCASTING: adding more than one method to an event
PUBLISHER: the one that executes the method (term used in broadcasting), only a single entity SUBSCRIBER: The methods that are being executed, can be multiple
LISTENER: the same thing as a subscriber but the term is used in multicasting
EVENT HANDLER: same thing as a subscriber/event listener so what the difference? it's basically the same thing, some say an eventlistener detect for the event to occur and the event handler "handles" or execute the code, ITS THE SAME THING PRACTICALLY!
action and func are just delegates that have been created and instantiated so 2 lines of code in a word, the difference is just in return types
ACTION: does not return anything while taking 0 or more than 1 input
FUNC: returns one thing and takes in parameters
if you don't do good with reading here is the best video on this topic
https://www.youtube.com/playlist?list=PLFt_AvWsXl0dliMtpZC8Qd_ru26785Ih_
Upvotes: 1
Reputation: 186668
Exposing a (public
) field
public EventHandler MyEventHandler;
is a bad practice: one can easily ruin the code with a small typo:
MyClass demo = new MyClass();
demo.MyEventHandler += MyMethod;
...
// Can you see the error? = instead of correct += ?
// MyMethod will not be called since this assignment
demo.MyEventHandler = MyReaction;
That's why you should use event which has been specially desinged for this
public event EventHandler MyEventHandler;
if we try the previous demo
we'll get compile time error:
MyClass demo = new MyClass();
...
demo.MyEventHandler = MyReaction; // <- doesn't compile, insist on +=
In very rare cases you may want explicit delegate-based fields, but these field should be concealed, say, be private
, not public
:
// We don't expose the field
private EventHandler m_MyEventHandler;
// ... But event:
public event EventHandler MyEventHandler {
add {
//TODO: extra logic on += operation
m_MyEventHandler += value;
}
remove {
//TODO: extra logic on -= operation
m_MyEventHandler -= value;
}
}
Upvotes: 13