Events in C#
In one of my previous articles, 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.
CodeProject
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 a type of particular delegate type for which they (events) are defined.
Example of declaring an event in C# is as follows:
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 notified 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 the following code:
SubscribeDelegate _blogSubscribeEvent;
public event SubscribeDelegate BlogSubscribeEvent
{
add { _blogSubscribeEvent += value; }
remove { _blogSubscribeEvent -= value; }
}
The above code adds and removes the event handler method from the invocation list of a 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, 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 two operations 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 operations. Suppose we try to assign a null
to the event, we will get the 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 BlogSubscriptionService
. 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 its 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 an 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 follows:
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 the 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 subscribers. Suppose I am using only delegates in the above example in place of event and I have created one more class named
AdvancedReader
as follows:
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 the 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 subscribers 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.
The post Understanding events in C# with Example appeared first on Dot Net For All.