Last active
January 4, 2019 16:39
-
-
Save konsfik/54b039f664ec2e799965ad823f99dcd5 to your computer and use it in GitHub Desktop.
An example of proper use of events in c#. In this example there are 10 event publishers and 1 event subscriber that subscribes to all of them. The code is heavily commented, to cover all aspects of its functionality.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
/// <summary> | |
/// Example use of events in c# | |
/// Author: Konstantinos Sfikas | |
/// Date: January 2019 | |
/// | |
/// In this example there are 10 event publishers and 1 event subscriber. | |
/// The event publishers are all instances of the NumberCounter class, | |
/// while the event subscriber is an instance of the Notifier class. | |
/// | |
/// As soon as any of the NumberCounter instances reaches its maximum number, | |
/// the MaxNumReached event is raised, and the Notifier instance responds to it | |
/// by printing some information to the console. | |
/// | |
/// </summary> | |
namespace EventsExample | |
{ | |
public class EventsTest | |
{ | |
static void Main(string[] args) | |
{ | |
Random rand = new Random(); | |
// instantiate the notifier (event subscriber) | |
Notifier notifier = new Notifier(); | |
List<NumberCounter> numberCounters = new List<NumberCounter>(); | |
// - create 10 instances of the NumberCounter class, | |
// - set their MaxNum property to a random value (10 to 20), | |
// - subscribe the notifier's Notify method to all of the NumberCounter instances | |
// - and store them in the numberCounters list | |
for (int i = 0; i < 10; i++) | |
{ | |
// - create an instance of the number counter class | |
// - with a random value (10 to 20) for the MaxNum property | |
NumberCounter numberCounter = new NumberCounter( | |
i, | |
0, | |
rand.Next(10, 20) // MaxNum is set to a random value (10 to 20) | |
); | |
// subscribe the Notify method of the notifier object | |
// to the numberCounter's MaxNumReached event | |
numberCounter.MaxNumReached += notifier.Notify; | |
// - store the numberCounter in the numberCounters list | |
numberCounters.Add(numberCounter); | |
} | |
// - increase the value of all number counters 20 times, | |
// to ensure that all of them reached their maximum value. | |
for (int i = 0; i < 20; i++) | |
{ | |
foreach (var nc in numberCounters) | |
{ | |
nc.IncreaseNumber(); | |
} | |
} | |
// wait for user input to end the programme | |
Console.ReadKey(); | |
} | |
} | |
// event subscriber | |
public class Notifier | |
{ | |
// - This method prints a description of the event to the console. | |
// | |
// - Note that it has the same signature as the MaxNumReached | |
// event's delegate (EventHandler<MaxNumEventArgs>) | |
// | |
// - Having the same signature (same return type and same parameters list) | |
// as the event's delegate, is a prerequisite so that this method can | |
// subscribed to the specific event. | |
public void Notify(object sender, MaxNumReachedEventArgs ea) | |
{ | |
Console.WriteLine( | |
String.Format( | |
"Number Counter {0} has reached its maximum number of {1} at {2}", | |
ea.id, | |
ea.num, | |
ea.eventTime.ToString() | |
) | |
); | |
} | |
} | |
// NumberCounter: event publisher class | |
// This class has only one public method (IncreaseNumber) | |
// which increases the value of the _num parameter by one. | |
// As soon as the value of _num is equal to _maxNum, | |
// the MaxNumReached event is raised. | |
public class NumberCounter | |
{ | |
// event declaration: | |
// Note that the event uses the EventHandler delegate type and that the | |
// custom type of event arguments (MaxNumReachedEventArgs) is used as a | |
// type parameter. | |
public event EventHandler<MaxNumReachedEventArgs> MaxNumReached; | |
// fields | |
private readonly int _id; | |
private int _num; | |
private readonly int _maxNum; | |
// properties | |
public int ID { get { return _id; } } | |
public int Num { get { return _num; } } | |
public int MaxNum { get { return _maxNum; } } | |
// constructor | |
public NumberCounter(int id, int initValue, int maxValue) | |
{ | |
_id = id; | |
_num = initValue; | |
_maxNum = maxValue; | |
} | |
// IncreaseNumber: method for increasing the number of the number counter | |
public void IncreaseNumber() | |
{ | |
if (Num < MaxNum) | |
{ | |
_num += 1; | |
if (Num == MaxNum) | |
{ | |
OnMaxNumReached(); | |
} | |
} | |
} | |
// OnMaxNumReached: method for raising the MaxNumReached event | |
// | |
// The method's name is On + [Event Name]: | |
// this is the standard way of naming event raising methods | |
// The method also performs a null check, to ensure that | |
// there are subscribers to the event, before raising it. | |
private void OnMaxNumReached() | |
{ | |
// if there is at least one subscriber to the event, | |
// then invoke it (raise it) | |
if (MaxNumReached != null) | |
{ | |
MaxNumReached.Invoke( | |
this, | |
new MaxNumReachedEventArgs() | |
{ | |
id = ID, | |
num = Num, | |
eventTime = DateTime.Now | |
} | |
); | |
} | |
} | |
} | |
// Custom event arguments definition: | |
// | |
// EventArgs is a class that is meant to represent the data that the | |
// event is carrying. | |
// | |
// In its pure form, EventArgs contains no parameters at all. | |
// However, by creating a subclass of the EventArgs class, we can | |
// include all the necessary fields that we want to use when | |
// raising the MaxNumReached event. | |
public class MaxNumReachedEventArgs : EventArgs | |
{ | |
public int id; | |
public int num; | |
public DateTime eventTime; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment