Events allow us two things:
- If something important has occurred object notifies its subscribers about that occurrence.
- Objects that listen to another object are notified about changes of that object.
To declare event, you use event keyword followed by the type of delegate for the event, meaning we have to declare delegate before we can use event.
Typically, to raise an event, you would use protected void method. Name of that method by convention goes should be like this: OnEventName. Method should raise eventĀ and provide two parameters object and EventArgs. Delegate upon whose type event uses should have two parameters: Object parameter is usually named sender and EventArgs parameter is named args. sender parameter is the source of the event. You should use EventArgs if you do not intend to send any parameters to subscriber, if on the other hand you wish to supply parameters create an class that inherits from from EventArgs and use that class as an parameter.
Example:
Lets create an application that is used to insert an employee to database. Upon inserting and after inserting few people should be notified, meaning we will have two events.
- First, when we start inserting employee in database, we will notify our System Administrator that process of inserting has started. Also we will provide Sys Admin with DateTime value which will represent time when insert operation has started.
- Second, after employee has been inserted in database, CEO, Website and System Admin will be notified.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
using System; using System.Threading; namespace Events { #region Delegates public delegate void NewEmployeeInsertedEventHandler(object source, EventArgs args); public delegate void NewEmployeeInsertingEventHandler(object source, EmployeeEventArgs args); #endregion class Program { static void Main(string[] args) { HRDepartment hr = new HRDepartment(); SystemAdmin sysAdmin = new SystemAdmin(); Ceo ceo = new Ceo(); WebSite webSite = new WebSite(); Employee newEmployee = new Employee() {Id = 1000, Name = "John Doe", Age = 25, Salary = 1000, YearsEmployed = 0}; // Subscribing SysAdmin to NewEmployeeInserting event hr.NewEmployeeInserting += sysAdmin.OnNewEmployeeInserting; // Subscribing subscribers to NewEmployeeInserted event hr.NewEmployeeInserted += sysAdmin.OnNewEmployeeInserted; hr.NewEmployeeInserted += ceo.OnNewEmployeeInserted; hr.NewEmployeeInserted += webSite.OnNewEmployeeInserted; // By calling InsertNewEmployee, few thing will happen: // 1. Process of inserting employee will start // 2. SysAdmin will be notiffied that process of inserting has started // 1. Employees information will be inserted in database // 1. All subscribers will be notified that employee has been inserted hr.InsertNewEmployee(newEmployee); Console.ReadKey(); } } public class HRDepartment { // Events public event NewEmployeeInsertedEventHandler NewEmployeeInserted; public event NewEmployeeInsertingEventHandler NewEmployeeInserting; public void InsertNewEmployee(Employee employee) { Console.WriteLine("Inserting new employee in database..."); // Firing NewEmployeeInserting event OnEmployeeInserting(); // TODO insert new employee in database // Because there is no logic to insert our employee // into database we are simulating wait time Thread.Sleep(3500); Console.WriteLine("New employee has been successfully inserted."); // Firing NewEmployeeInserted event OnNewEmployeeInserted(); } protected virtual void OnNewEmployeeInserted() { // Checking if there are any subscribers to our event if (NewEmployeeInserted != null) { // as parameters whe are sending // this instance of a class // and no EventArgs NewEmployeeInserted(this, EventArgs.Empty); } } protected virtual void OnEmployeeInserting() { if (NewEmployeeInserting != null) { // as parameters we are sending // this instance of a class // and EmployeeEventArgs instance with DateTime value NewEmployeeInserting(this, new EmployeeEventArgs() {TimeOfInserting = DateTime.Now}); } } } public class Employee { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public int YearsEmployed { get; set; } public double Salary { get; set; } } public class EmployeeEventArgs : EventArgs { // DateTime value that will be shown while // inserting new employee public DateTime TimeOfInserting { get; set; } } public class Ceo { // Method signature must match delegate NewEmployeeInsertedEventHandler public void OnNewEmployeeInserted(object source, EventArgs args) { Console.WriteLine("Ceo notified about new employee."); } } public class WebSite { // Method signature must match delegate NewEmployeeInsertedEventHandler public void OnNewEmployeeInserted(object source, EventArgs args) { Console.WriteLine("WebSite notified about new employee."); } } // Because SysAdmin is subscribed to two events that consume two diferent delegates // we need two different methods for subscription public class SystemAdmin { // Method signature must match delegate NewEmployeeInsertingEventHandler public void OnNewEmployeeInserting(object source, EmployeeEventArgs args) { Console.WriteLine("Notification to SysAdmin: A new employee is beeing created {0}", args.TimeOfInserting); } // Method signature must match delegate NewEmployeeInsertedEventHandler public void OnNewEmployeeInserted(object source, EventArgs args) { Console.WriteLine("SysAdmin notified about new employee."); } } } |
You can also download entire solution for easier readability.
If you prefer using Action delegate instead of declaring delegates you can easily doe that. Just replace following code in HRDepartment class:
1 2 3 4 5 6 7 8 |
// Events // comment following two lines //public event NewEmployeeInsertedEventHandler NewEmployeeInserted; //public event NewEmployeeInsertingEventHandler NewEmployeeInserting; // and insert these two lines public event Action<object, EventArgs> NewEmployeeInserted; public event Action<object, EmployeeEventArgs> NewEmployeeInserting; |
For now we will finish our journey with Delegates and return to Reflection.