In order to understand custom event accessors, we need to clarify why they are needed and how they are used. In this guide, we will introduce the concept of events, then take a look at how events and their accessors can be used to interact between classes. In C#, a typical example of this would be a Windows Forms
or Web Application
.
Let's take a live example. We have a GUI (Graphical User Interface) application, which consists of buttons, text boxes etc. Each component is made up of its own class, and each class provides a functionality—for example, a button push sends a notification to a web application or invokes a local application on the machine. At the very heart of this are events. We categorize classes either by publisher or subscriber. The publisher is the class that sends or raises the event, and the subscriber receives the event and takes specific action based on it.
A few rules to keep in mind when it comes to events:
delegates
and EventArgs base class
.I believe it's best to demonstrate this with a mechabot
example, for which the code looks like this.
1using System;
2namespace Pluralsight
3{
4 public class Machine
5 {
6 private int _utilization = 0;
7 private int _safeutil = 70;
8 public delegate void StressLimitExceededEventHandler(object source, EventArgs e);
9 public event StressLimitExceededEventHandler StressLimitExceeded;
10 public virtual void OnStressLevelExceeded(EventArgs e)
11 {
12 StressLimitExceeded?.Invoke(this, e);
13 }
14 public int Performance
15 {
16 get
17 {
18 return _utilization;
19 }
20 }
21 static void MachineStressLimitExceeded(object source, EventArgs e)
22 {
23 Machine mechabot = (Machine)source;
24 Console.WriteLine("Stress level warning ({0} %)", mechabot.Performance);
25
26
27 }
28 public void StressTest(int utilization)
29 {
30 int oldUtilization = _utilization;
31 _utilization += utilization;
32
33 if (oldUtilization <= _safeutil && _utilization > _safeutil)
34 OnStressLevelExceeded(new EventArgs());
35 }
36 public static void Main()
37 {
38 Machine mechabot = new Machine();
39 mechabot.StressLimitExceeded += new StressLimitExceededEventHandler(MachineStressLimitExceeded);
40 Console.WriteLine($"The utilization is {mechabot.Performance} %");
41 mechabot.StressTest(60);
42 Console.WriteLine($"The utilization is {mechabot.Performance} %");
43 mechabot.StressTest(15);
44 Console.WriteLine($"The utilization is {mechabot.Performance} %");
45 Console.ReadKey();
46 }
47 }
48}
Executing the code produced the following output.
1The utilization is 0 %
2The utilization is 60 %
3Stress level warning (75 %)
4The utilization is 75 %
Let's dissect the example. The Main()
function is what drives the whole demonstration. We have a StressTest
function, which takes a utilization
argument, which will increase the mechabot's utilization. In here we check whether the old utilization and the one after the increase surpass _safeutil
, which is set to 70
. One of the most important concepts of event handling is demonstrated here in which the OnStressLevelExceeded
is fired when the conditions are met.
The delegate we have is called StressLimitExceededEventHandler
, and it is responsible to hold the details of the subscriber to the event. The event StressLimitExceededEventHandler
is also created, which will be able to provide us with the subscription. The associated event method is called OnStressLevelExceeded
and will be invoked when the subscribed event is fired and the conditions are met. This class is glued together by this concept and provides a sufficient demonstration as to how you can create your own event handlers.
In this guide you received a short introduction to events and some general rules and steps for creating them. Then the Machine
class demonstrated how to glue the concepts together and how event handlers can be incorporated into your application. I hope this has been informative to you and I would like to thank you for reading it.