Events in C#
In one of my previous article I have discussed about the delegates in C#. In this article I will discuss about the events in C# and .NET framework and I will use C# as the programming language for the real programming example.
What is an Event?
Events are based on the publisher and subscriber model of programming. There is a type which is publisher or broadcaster which allows the type or instance of type(itself) to notify other objects (which are subscribers ) that something has happened. Events are type(publishers) members that allow this interaction.
Events use the delegates for this publisher and subscriber model of interaction. Basically events are type of particular delegate type for which they(events) are defined
Example of declaring an event in C# is as following
public delegate void MyDelegate(); public event MyDelegate MyDelegateEvent;
Interesting Analogy and Example
It had always been confusing for me to understand the events when I was learning .NET. But here in this article I want to make it simple for the readers of this article to understand the concept with the help of this example and an analogy.
Problem:
Suppose I(Writer class) have a blog class and my blog has few subscribers(Reader class) and I want to notify the subscribers of my blog to be notifies whenever I publish an article on my blog.
Solution:
I will explain the design of this solution and going though it I will discuss the concepts of the events.
The above figure shows the layout architecture of the project which I have used as a sample project to describe about the events. Please note that this same project can be designed in a more efficient way using the OOP concepts but that is not the purpose of this article.
Below is the description of the classes involved in the project.
- BlogNS – Is the blog class which has a property of type BlogSubscriptionService and a property for Name of the blog as shown below
public class Blog { public string BlogName { get; set; } public BlogSubscriptionSerivce BlogSubscribtionService { get; set; } public Blog() { BlogSubscribtionService = new BlogSubscriptionSerivce(); } }
- BlogSubscrptionService – This is a class which is basically the publisher or broadcaster of the events which the subscriber(Reader) class would be subscribing for.
public delegate void SubscribeDelegate(string blogName, string articleName); public class BlogSubscriptionSerivce { public event SubscribeDelegate BlogSubscribeEvent; public void ArticleCompleted(string articleName, string blogName) { if (BlogSubscribeEvent != null) BlogSubscribeEvent(articleName, blogName); } }
As we can see from the above code , we have an event defined in the class named BlogSubscribeEvent which is of type SubscribeDelegate delegate. This class knows when to broadcast the event, by invoking the event in the ArticleCompleted() method.
What happens behind the screen is that whenever we define an event the compiler translates the code to something close to following codeSubscribeDelegate _blogSubscribeEvent; public event SubscribeDelegate BlogSubscribeEvent { add { _blogSubscribeEvent += value; } remove { _blogSubscribeEvent -= value; } }
The above code adds and removed the event handler method from the invocation list of particular delegate.
- Events – This is my client application where all the subscription and publishing of the events is taking place, the code of this class I will explain once I am done with explaining all the parts of the project.
- ReaderNS – Reader namespace contains a Reader class which is a type which would be subscribing for the event of the BlogSubscrptionService. It means the instance of this class are the subscribers for the blog class.
public class Reader { public string ReaderName { get; set; } public Reader(string readerName) { ReaderName = readerName; } public void SubscribeForBlog(Blog blog) { blog.BlogSubscribtionService.BlogSubscribeEvent += BlogSubscribtionService_BlogSubscribeEvent; } private void BlogSubscribtionService_BlogSubscribeEvent(string articleName, string blogName) { Console.WriteLine("{0} is read by {1} in the blog {2}", articleName, ReaderName, blogName); } }
In the class code we can see that particular reader instance can subscribe for the blog in the SubscribeForBlog() method.
Here I want to tell you what exactly subscription means and how it is done. As we can see from the above code that we are subscribing to the BlogSubscribeEvent event of the BlogSubscribtionService using the code below .
blog.BlogSubscribtionService.BlogSubscribeEvent += BlogSubscribtionService_BlogSubscribeEvent;
One point I want to bring to your notice is that we can only perform only two operation on the Event accessors and they are “+=” and “-=” which denotes the add and removing of the event handler method for particular event. We cannot perform any other operation on the event apart from these two operation. Suppose if we try to assign a null to the event we will get following error.
I have handled the subscription of the BlogSubscribeEvent event of the BlogSubscribtionService using the handler method BlogSubscribtionService_BlogSubscribeEvent which should have the same method signature as of the SubscribeDelegate delegate present in the BlogSubscrptionService class.
- WriterNS – Writer namespace contains a class, the instance of which is the writer of the blog. This class has a Blog property.One the blog is completed the ArticleCompleted() method of this instance is called which would in turn call the ArticleCompleted() method of the BlogSubscriptionSerivce. This method then invokes the BlogSubscribeEvent which notifies all the readers of this blog that a new article has been completed on the blog using the event handler methods which we have attached in the Reader class.
public class Writer { private Blog blogProp; public Writer(Blog blog) { this.blogProp = blog; } public void ArticleCompleted() { if (blogProp == null) blogProp = new Blog(); blogProp.BlogSubscribtionService.ArticleCompleted("Events in .NET", blogProp.BlogName); } }
Till now I have discussed all the components of the project which I have developed to explain about the events in .NET system.
Now it’s time to run the project and see the outcome of the project and analyze it.
As discussed earlier for the Client which will be doing all the operation, let’s check it’s code.
static void Main(string[] args) { Blog myBlog = new Blog() { BlogName = "Dot Net For All" }; myBlog.BlogSubscribtionService = new BlogSubscriptionSerivce(); Reader reader1 = new Reader("Reader1"); reader1.SubscribeForBlog(myBlog); Reader reader2 = new Reader("Reader2"); reader2.SubscribeForBlog(myBlog); Writer writer = new Writer(myBlog); writer.ArticleCompleted(); Console.Read(); }
By looking at the code itself it should be easily understandable, Writer has a blog(myBlog) which has two subscribers(readers) i.e. reader1 and reader2, who want to get notified whenever an article is completed.
Let’s run the project and see the output.
As we have already discussed that two of the readers have subscribed for the BlogSubscribeEvent of the BlogSubscriptionSerivce class, we can see that as soon as article is completed by the reader, both of the readers get the notification that the article has been completed.
This was a small article about the usage of events in .NET using C# as programming language. But why events, what would have been the scenario if I would have not used the event keyword while declaring event in the BlogSubscriptionSerivce class, in that case the definition would have been as following
public SubscribeDelegate BlogSubscribeEvent;
which is nothing but defining a property of type SubscribeDelegate. As we know that events only allow two operators to operate on itself i.e. “+=” and “-=”. On the flip side in the absence of the event keyword, the other operations can also be worked by other subscribers, which are advantages of events as mentioned in the following points.
Why we should use Events in .NET
- In absence of the events, if we are dealing with the only delegates in that case, there are chances that one of the subscribers can reassign the delegate with the new handler reference as shown in the example below.
public void SubscribeForBlog(Blog blog) { blog.BlogSubscribtionService.BlogSubscribeEvent = new BlogSubscriptionService.SubscribeDelegate(BlogSubscribtionService_BlogSubscribeEvent); }
- All the subscribers can be cleared by any one of the subscriber. Suppose I am using only delegates in the above example in place of event and I have created one more class named AdvancedReader as following
public class AdvancedReader { public string ReaderName { get; set; } public AdvancedReader(string readerName) { ReaderName = readerName; } public void SubscribeForBlog(Blog blog) { blog.BlogSubscribtionService.BlogSubscribeEvent += BlogSubscribtionService_BlogSubscribeEvent; } private void BlogSubscribtionService_BlogSubscribeEvent(string articleName, string blogName) { Console.WriteLine("{0} is read by {1} in the blog {2} on Mobile", articleName, ReaderName, blogName); } }
And I am calling all the classes in following manner in the client,
Blog myBlog = new Blog() { BlogName = "Dot Net For All" }; myBlog.BlogSubscribtionService = new BlogSubscriptionSerivce(); AdvancedReader advReader = new AdvancedReader("Advanced Reader"); advReader.SubscribeForBlog(myBlog); Reader reader1 = new Reader("Reader1"); reader1.SubscribeForBlog(myBlog); Reader reader2 = new Reader("Reader2"); reader2.SubscribeForBlog(myBlog); Writer writer = new Writer(myBlog); writer.ArticleCompleted(); Console.Read();
But in the Reader class I have nullified the delegate as shown below
public void SubscribeForBlog(Blog blog) { blog.BlogSubscribtionService.BlogSubscribeEvent = null; }
It means that all the functions pointer to the delegate can be nullified by any one subscriber if we are not using delegates.
- Any one of the subscriber can broadcast the event to other subscribers when we are dealing with only delegates and not events.
In this article I have described about the article in the .NET framework and why we should use events in the .NET framework. After reading the article I suppose that the reader should be able to understand about the events.
Please find the solution for Solution for Events here and do let me know your thoughts about the article.