C# Events

Inventory stock example

The following snippet is a console application for an inventory system that keeps track of cars in stock and will automatically restock/order when inventory has a certain number of cars left.

using System;

namespace Test
{
    public class CarStock
    {
        //declare variables
        public string carModel;
        private int stock;

        //declare multicast delegate
        public delegate void LowOnStock(object sender, EventArgs e);

        //published event (StockLow) - needs a delegate
        public event LowOnStock LowStock;

        //car constructor
        public CarStock(string modelName, int inventory)
        {
            carModel = modelName;
            stock = inventory;
        }

        //method reduces stock based on how many cars sold
        public void ReduceStock(CarStock c, int numOfSales)
        {
            //application should only successfully deduct stock if inventory is equal or greater than sales
            if (c.stock >= numOfSales)
            {
                //subtract number of sold cars from inventory
                c.stock = c.stock - numOfSales;
                Console.WriteLine("There are {0} cars remaining in stock.", stock);

                //raise LowStock event when inventory reaches 5 or less after reducing stock
                if (c.stock <= 5)
                {
                    //trigger event
                    LowStock?.Invoke(this, EventArgs.Empty);

                    //call method that reorders stock
                    ReorderStock(c);
                }
            }
            else
            {
                //error message: number of sales cannot be more than stock
                Console.WriteLine("Invalid input. The number of sales cannot be greater than inventory available.");
            }   
        }

        //method that redorders stock
        public void ReorderStock(CarStock c)
        {
            //placeholder variable for number of additional stock order
            int order = 0; 

            //loop ensures that user enters a positive integer for their order
            while (true)
            {
                //prompt user for stock order
                Console.WriteLine("How many cars do you want to reorder?");
                order = Convert.ToInt32(Console.ReadLine());

                if (Program.IsPositiveInteger(order) == true)
                {
                    //break out of the loop if valid
                    break;
                }
                else
                {
                    //prompt for a retry when invalid
                    Console.WriteLine("Error: Invalid input. Please, try again.");
                }
            }

            //adds reorder amount to the stock of cars
            c.stock += order;
            Console.WriteLine("You now have {0} {1} cars", c.stock, c.carModel);
        }
    }

    //subscriber class - subscribes to published event
    public class Counter
    {
        //declare class member
        private string CounterName;

        //class constructor
        public Counter(string Name)
        {
            CounterName = Name;
        }

        //method that performs the billing 
        public void Sales(CarStock c, int amount)
        {
            Console.WriteLine("You have sold {0} {1} cars.", amount, c.carModel);
            c.ReduceStock(c, amount);
        }

        //Function that acts as event ...
        //handler for LowStock to receive the notification
        public void LowStockHandler(object Sender, EventArgs e)
        {
            Console.WriteLine("Notice: There is currently low stock for {0} cars.", ((CarStock)Sender).carModel);
        }
    }

    class Program
    {
        //method used for checking if a number entered is a positive integer
        //returns boolean
        public static bool IsPositiveInteger(int number)
        {
            //checks if number is greater than 0 and is a whole number (positive integer)
            if (number > 0 && (number % 1) == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        static void Main(string[] args)
        {
            //create new Counter object
            Counter billingCounter1 = new Counter("Richard");

            //declaration of variables
            int currentStock = 0; //placeholder value for stock
            int soldCars = 0; //placeholder value for sold cars

            //prompts user for current stock
            Console.WriteLine("How many cars do you have in stock?");

            //loop continues to prompt stock number until valid input is entered
            while (true)
            {
                try
                {
                    var input = Console.ReadLine();
                    currentStock = int.Parse(input);

                    //stock cannot be 0 or less
                    if (currentStock <= 0)
                    {
                        Console.WriteLine("Error: Please enter a positive number. Try again.");
                    }
                }
                catch (FormatException)
                {
                    Console.WriteLine("Error: Invalid input. Please, try again.");
                }

                //uses created IsPositiveInteger method ... 
                //to check if number is a positive integer ...
                //since the number of cars cannot be negative and needs to be a whole number 
                if (IsPositiveInteger(currentStock) == true)
                {
                    //break the loop if the number is a positive integer
                    break;
                }
            }

            //create CarStock object
            CarStock carObject = new CarStock("Ford Pinto", currentStock);
            //attach LowOnStock handler to the event through the delegate
            carObject.LowStock += new CarStock.LowOnStock(billingCounter1.LowStockHandler);

            //application supposedly runs indefinitely
            while (true)
            {
                //prompts user for how many cars sold
                Console.WriteLine("How many cars did you sell?");

                //loop continues to prompt for number of sold cars ... 
                //until valid input is entered
                while (true)
                {
                    try
                    {
                        //takes user input and parses as int
                        var input = Console.ReadLine();
                        soldCars = int.Parse(input);

                        //validates number of cars sold 
                        if (soldCars <= 0)
                        {
                            //sold cars cannot be less than 0
                            Console.WriteLine("Error: Please enter a whole number greater than 0.");
                        }
                        else if (soldCars > currentStock)
                        {
                            //sold cars cannot exceed current stock amount
                            Console.WriteLine("Error: You cannot sell more cars than available stock.");
                        }
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine("Error: Invalid input. Please, try again.");
                    }

                    //uses created IsPositiveInteger method ... 
                    //to check if number is a positive integer ... 
                    //since sold cars cannot be negative and needs to be a whole number ...
                    //also checks if the number is not greater than stock
                    if (IsPositiveInteger(soldCars) == true && soldCars <= currentStock)
                    {
                        //break the loop if the number is valid
                        break;
                    }
                }

                //billing process
                //uses the created CarStock object and sold cars
                billingCounter1.Sales(carObject, soldCars);
            }
        }
    }
}

If there are only 5 or less Ford Pintos left in stock, the LowStock event is triggered. The console application asks the user to enter a valid number to resupply the inventory with that number of Ford Pintos. When successful, the order is complete.

Testing output screenshots: image.png image.png image.png

Note: This is a follow-up example project that also uses delegates and events.