Why do we use Events in C# instead of delegates? Is it possible to use with delegates alone? Why add events? Some of the common questions I get particularly to Junior Developers. Today, we will show some of the major reasons why.
I divided the code to Team Developer and Team Client. Team Developer will code the delegate and Team Client will instantiate the class and subscribe to delegate.
Team Developer
First lets say we want to use delegates alone using the following code:
public delegate void YourLoggingHere();
public class WhyUseEvents
{
public YourLoggingHere MyLogging;
public void MyMainProgram()
{
ExecuteValidation();
}
private void ExecuteValidation()
{
//Execution of validation and logic here
//With some business rules etc.
if (MyLogging != null)
{
MyLogging.Invoke();
}
}
}
As you can see, Team Developer declare a "YourLoggingHere" delegate, and declare it as property named "MyLogging". Now Team Client can instantiate this class and use this property and add methods to it.
Team Client
On the following example, Team Client wants to use the class and add methods to "MyLogging" delegate. They can add as many methods as they want. On this case, they only added one:
WhyUseEvents why = new WhyUseEvents();
why.MyLogging += () =>
{
Console.WriteLine("Hi I am subscribing to the delegate.");
};
Now both Team Developer and Team Client can use the code properly. But there is a catch. Team Client can directly invoke the delegate!
Issues
WhyUseEvents why = new WhyUseEvents();
why.MyLogging += () =>
{
Console.WriteLine("Hi I am subscribing to the delegate.");
};
why.MyLogging.Invoke(); //Team Client here can directly invoke the delegate!
As you can see on the above code, Team Client can directly invoke the delegate without Team Developer knowing it. It's not a good way to encapsulate your methods and properties since there are other validations to be executed first before invoking the delegate!
Review the Code
Let's review the code, before you can invoke "MyLogging" delegate, there are validation and business logic first before you can finally invoke the delegate.
private void ExecuteValidation()
{
//Execution of validation and logic here
//With some business rules etc.
if (MyLogging != null)
{
MyLogging.Invoke();
}
}
Solution? Yes, Events!
Team Developer solved the problem by adding the event keyword:
//public YourLoggingHere MyLogging;
public event YourLoggingHere MyLogging;
Team Client cannot directly invoke the delegate. If they do, it will trigger an error as shown below:
why.MyLogging.Invoke();
//The event 'WhyUseEvents.MyLogging' can only appear on the left hand side of += or -= (except when used from within the type 'WhyUseEvents')
This is a simplified explanation on why we use events even though we can already use delegates:
- To provide encapsulation and not exposing business logic
- To prevent Team Client from clearing all assign methods to delegates (You cannot do that for events):
why.MyLogging = null;
- And of course to prevent invocation of the delegates.
Cheers I hope you learn on my post and happy coding!
Top comments (6)
not sure why no one appreciate this gem of an answer. possibly no one is asking questions anymore.
Thank you.
You're welcome! I am glad you like my post :)
Why we do not make the delegate private and provide a public method to add the method`s pointers to it?, this will prevent the Team Client from directly invoke the delegate.
This is gem, nice explaination :D
You're welcome! I am glad you like my post :)
Precious answer! Thank you