Why Do We Need the "Event" Keyword While Defining Events

Why do we need the event keyword while defining events?

Field-like events and public fields of delegate types look similar, but are actually very different.

An event is fundamentally like a property - it's a pair of add/remove methods (instead of the get/set of a property). When you declare a field-like event (i.e. one where you don't specify the add/remove bits yourself) a public event is created, and a private backing field. This lets you raise the event privately, but allow public subscription. With a public delegate field, anyone can remove other people's event handlers, raise the event themselves, etc - it's an encapsulation disaster.

For more on events (and delegates) read my article on this topic. (At some point I need to update this for C# 4, which changes field-like events very slightly. The gist of it is still correct though.)

Purpose of event keyword

The event keyword lets you specify add and remove operations inline with the declaration.

private Action _myEvent;

public event Action MyEvent
{
add
{
Console.WriteLine("Listener added!");
_myEvent += value;
}
remove
{
Console.WriteLine("Listener removed!");
_myEvent -= value;
}
}

C# - Event keyword advantages?

What is the advantage of using the event keyword other than for modifying how the delegate can be accessed?

That is the primary advantage of using the event keyword. You use an event over just a raw delegate to prevent the delegate from being invoked or cleared from outside the scope of the class it is defined in, because in the case of events it is the responsibility of that class to invoke the event. External entities shouldn't be invoking it directly (they can and should be invoking the event indirectly), nor should they "care" about whether there are any other event handlers or be involved in touching them (by, for example, assigning an entirely new delegate to the field).

The specific case of wanting to allow sub-classes to fire the event is most commonly solved by having the class that defines the event creating a protected method that does nothing but fire the event. Such methods will, by convention, have the same name as the event but with "On" prefixing it.

Yes, you could create your own type that logically represents an event, is a wrapper for a delegate, and limits the functions that can be performed on that event to those that "should" be able to perform them (possibly using slightly different rules than the C# event keyword uses. This is something that is frequently used in other languages that don't have an event keyword (or possibly even delegates). The C# designers simply realized that this was a very common pattern, and felt that it was worth the energy to add the keyword to the language to help minimize the boilerplate code required to create a logical "event".

Another benefit of using the event keyword, as opposed to just having some type of delegate as a property, is that you make your intentions much clearer. If I see just a delegate property the implication is generally that it represents one method. Yes, all delegates in C# are multicast delegates, so that's not true, but it's unusual for people to leverage that functionality outside of events. People think that an Action represents one action, not a list of actions. Events also have special treatment with respect to the C# documentation. They are all listed separately, they have different icons in visual studio, etc. This all helps make the intentions and semantics of the member much clearer to someone using the class at a glance.

Finally, the event keyword ensures that there is synchronization between multiple threads, which isn't performed by the Delegate class. If multiple threads go to add handlers to an event at the same time, the event keyword ensures both are added. If you just publicly expose a delegate it's possible for one to overwrite the other due to a race condition and have one handler end up dropped on the floor. If you roll your own Event class you could provide this functionality, but it is both more boilerplate code and something that's pretty darn easy to mess up (either resulting in leaving race conditions in, or excessive synchronization resulting in lost performance).

Events, Delegates vs ActionsT

Action<T> is just an easy generic way to use delegates. It's equivalent to delegate MyDelegate(T arg)
It was added to save you some typing and it really saves the reader a LOT of hassle when trying to figure out what your delegate uses as parameters.

The event keyword has special meaning. It prevents this delegate from being triggered outside of the class. See this excellent answer for a discussion of why event is important and when you would use it (or not).

event EventHandler vs EventHandler

They seems to be alike, but really different.

With event keyword, you are making them something like properties, which means you can register them in public, while maintain a private back-end.

However, without event keyword, it's just a public delegate field, and anyone can remove or modify others' events, which is a "encapsulation disaster" as @Jonskeet said.

Check this article by Jon Skeet, it's very helpful :)

Edit:

What I summarized above was not my original thinking, all credits to @Jonskeet's post.

Why do Events need Delegates? Why do we even Need Events?

but enough to know that delegate datatype is a single cast delegate. delegate void is a multicast delegate - a list of references to methods.

Not true. All "normal" delegates are multicast, even if they have a non void return type.

Question 1: I think myObject is the target, and SomeMethod is the method to reference, but I'm only passing one input. So is myObject.SomeMethod compiled to a string and is the string split by the period? Ridiculous I know.

No, myObject.SomeMethod is a method group. This way of delegate instance creation involves a bit of compiler magic.

multicastdelegate+=newmethodtobereference

If multicastdelegate is a normal delegate variable, this is equivalent to multicastdelegate = multicastdelegate + newmethodtobereference i.e. it creates a new delegate that calls several methods, and assigns it to multicastdelegate.


Now to your main question: What's the purpose of events?

Events have delegate types. They behave similarly to properties. Their purpose is encapsulation, in particular they only allow consumers to subscribe(+=) and unsubscribe(-=) but not to read the value of the event.

Properties are a combination of two methods: get and set.

Events are a combination of two public methods subscribe and unsubscribe, and in the case of a field-like event also something similar to a private getter.

why to declare delegate with event i, I don't see the use of the keyword event?

Sure:

// With events...
public class Button
{
public event EventHandler Click;
}

public void Client
{
public void Method(Button button)
{
// This is all I can do...
button.Click += SomeHandler;
}
}

// With plain delegate fields or properties...
public class Button
{
public EventHandler Click { get; set; }
}

public void Client
{
public void Method(Button button)
{
// Who cares if someone else is already subscribed...
button.Click = SomeHandler;

// And let's just raise the event ourselves...
button.Click(button, EventArgs.Empty);
}
}

In other words, with events you've got a controlled implementation of the pub/sub pattern - separate subscribers can't interfere with each other (except perhaps by throwing an exception within their handler) and only the publisher can "publish" (call the handlers).

keyword event in c#

Because of encapsulation. If keyword 'event' will be removed then you will be able to invoke 'event' and even change it's subscriptions from external classes which do not own the event. See Jon's answer here. With event keyword you're sharing an event, without it you're giving an access to delegate.

what role event delegates play?

This can help you to understand events and delegates:

Events in .NET are based on the delegate model. The delegate model follows the observer design pattern, which enables a subscriber to register with and receive notifications from a provider. An event sender pushes a notification that an event has happened, and an event receiver receives that notification and defines a response to it. This article describes the major components of the delegate model, how to consume events in applications, and how to implement events in your code.

An event is a message sent by an object to signal the occurrence of an action. The action can be caused by user interaction, such as a button click, or it can result from some other program logic, such as changing a property’s value. The object that raises the event is called the event sender. The event sender doesn't know which object or method will receive (handle) the events it raises. The event is typically a member of the event sender; for example, the Click event is a member of the Button class, and the PropertyChanged event is a member of the class that implements the INotifyPropertyChanged interface.

To define an event, you use the C# event or the Visual Basic Event keyword in the signature of your event class, and specify the type of delegate for the event. Delegates are described in the next section.

Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and Overridable (in Visual Basic). Name this method OnEventName; for example, OnDataReceived. The method should take one parameter that specifies an event data object, which is an object of type EventArgs or a derived type. You provide this method to enable derived classes to override the logic for raising the event. A derived class should always call the OnEventName method of the base class to ensure that registered delegates receive the event.

A simple example is the Button control: when you click on it, the event OnClick is raised and the control call all delegates that have suscribed to it using:

Click += SomeMethod;

Or (it is the same):

Click += new EventHandler(SomeMethod);

If fact, it adds a reference to the method in the event handler list.

An event is just a list of methods to call in case of the event is raised, like with the button click.

A delegate is just a signature of a method without a body implementation, also called a prototype, to be used as a type, to have strong typing when adding events to an event handler like the button click. So when you assign a method implemented, by its name, it must match the delegate signature (return type and parameters, the name of the delegate itself is not pertinent except for humans).

We also can use lambda:

myButton1.Click += (sender, e) => Close();

myButton2.Click += (sender, e) => { MessageBox.Show("Closing"); Close() };

Handling and raising events (MS Docs)

C# - Events(TutorialsPoint)

C# - Events (TutorialsTeacher)

What are C# Events? (YouTube)

C# Tutorial: Events/Event Handlers (YouTube)



Related Topics



Leave a reply



Submit