Meta Description:
Learn how to pass data into event handlers in C#. This article explains how to use custom event data in a stock management system, with assignments at three levels of difficulty.
Introduction
In C#, event handlers often need to pass data to subscribers so that they can act based on the event context. The EventHandler
delegate allows you to pass data using EventArgs
. You can extend EventArgs
to create custom data for your events, making event-driven communication more efficient and informative.
In this article, we’ll explore how to pass data into event handlers using a stock management system example. We’ll cover the creation of custom event data classes and demonstrate how event subscribers can handle and utilize this data. Finally, we’ll provide assignments to help you apply these concepts at different levels of difficulty.
1. The Importance of Passing Data into Event Handlers
When an event occurs, the event handler often needs to know details about what happened. For example, in our stock management system, when stock levels fall below a certain threshold, we may want to pass the current stock level and the product’s details to the event subscribers. This data can be useful for actions such as notifying a supplier or adjusting inventory.
In C#, event data is typically passed using the EventArgs
class or its generic equivalent, EventHandler<T>
. You can extend EventArgs
to include the specific data your event needs to communicate.
2. Stock Management System Example with Custom Event Data
Let’s enhance our stock management system by passing more detailed data to event subscribers. We’ll create a custom event data class, StockChangedEventArgs
, which will include both the old and new stock levels. This allows the event subscribers, such as the WarehouseManager
, to react more effectively to changes in stock levels.
Step 1: Create a Custom EventArgs Class
First, we’ll create the StockChangedEventArgs
class, which inherits from EventArgs
and holds the stock details.
using System;
public class StockChangedEventArgs : EventArgs
{
public string ItemName { get; set; }
public int OldStock { get; set; }
public int NewStock { get; set; }
public StockChangedEventArgs(string itemName, int oldStock, int newStock)
{
ItemName = itemName;
OldStock = oldStock;
NewStock = newStock;
}
}
Step 2: Modify the InventoryManager to Use the Custom EventArgs
Next, we modify the InventoryManager
to use StockChangedEventArgs
when raising the StockLow
event. We’ll pass the old and new stock levels to subscribers.
public class InventoryManager
{
public event EventHandler<StockChangedEventArgs> StockLow;
private int _stockLevel;
public string ItemName { get; set; }
public InventoryManager(string itemName, int initialStock)
{
ItemName = itemName;
_stockLevel = initialStock;
}
public void ProcessSale(int quantity)
{
int oldStock = _stockLevel;
_stockLevel -= quantity;
Console.WriteLine($"{quantity} {ItemName}(s) sold. Current stock: {_stockLevel}");
if (_stockLevel < 5)
{
OnStockLow(oldStock, _stockLevel);
}
}
protected virtual void OnStockLow(int oldStock, int newStock)
{
StockLow?.Invoke(this, new StockChangedEventArgs(ItemName, oldStock, newStock));
}
}
Step 3: Update Subscribers to Handle the Custom Event Data
Now we’ll modify the WarehouseManager
to handle the new event data, reacting to the old and new stock levels passed through StockChangedEventArgs
.
public class WarehouseManager
{
public void Restock(object sender, StockChangedEventArgs e)
{
Console.WriteLine($"Warehouse notified: Restock {e.ItemName}. Stock changed from {e.OldStock} to {e.NewStock}.");
}
}
Step 4: Run the Program
Finally, we’ll simulate the stock change and trigger the event.
public class Program
{
public static void Main(string[] args)
{
InventoryManager inventory = new InventoryManager("Laptop", 10);
WarehouseManager warehouse = new WarehouseManager();
// Subscribe to the StockLow event
inventory.StockLow += warehouse.Restock;
// Simulate sales that reduce stock and trigger the event
inventory.ProcessSale(3); // Stock = 7, no event
inventory.ProcessSale(4); // Stock = 3, event triggered
}
}
Explanation:
- The
InventoryManager
tracks stock levels and raises theStockLow
event when stock falls below 5. - The
StockChangedEventArgs
class holds information about the old and new stock levels. - The
WarehouseManager
responds to the event by processing the stock change and printing a message with the old and new stock values.
3. Why Use Custom Event Data?
Using custom event data allows you to pass meaningful information to subscribers, making event-driven systems more powerful and flexible. In our stock management system, the WarehouseManager
can take different actions based on both the old and new stock levels. This additional context improves the ability to react appropriately to changes.
Full Code: Stock Management System with Custom Event Data
using System;
public class StockChangedEventArgs : EventArgs
{
public string ItemName { get; set; }
public int OldStock { get; set; }
public int NewStock { get; set; }
public StockChangedEventArgs(string itemName, int oldStock, int newStock)
{
ItemName = itemName;
OldStock = oldStock;
NewStock = newStock;
}
}
public class InventoryManager
{
public event EventHandler<StockChangedEventArgs> StockLow;
private int _stockLevel;
public string ItemName { get; set; }
public InventoryManager(string itemName, int initialStock)
{
ItemName = itemName;
_stockLevel = initialStock;
}
public void ProcessSale(int quantity)
{
int oldStock = _stockLevel;
_stockLevel -= quantity;
Console.WriteLine($"{quantity} {ItemName}(s) sold. Current stock: {_stockLevel}");
if (_stockLevel < 5)
{
OnStockLow(oldStock, _stockLevel);
}
}
protected virtual void OnStockLow(int oldStock, int newStock)
{
StockLow?.Invoke(this, new StockChangedEventArgs(ItemName, oldStock, newStock));
}
}
public class WarehouseManager
{
public void Restock(object sender, StockChangedEventArgs e)
{
Console.WriteLine($"Warehouse notified: Restock {e.ItemName}. Stock changed from {e.OldStock} to {e.NewStock}.");
}
}
public class Program
{
public static void Main(string[] args)
{
InventoryManager inventory = new InventoryManager("Laptop", 10);
WarehouseManager warehouse = new WarehouseManager();
// Subscribe to the StockLow event
inventory.StockLow += warehouse.Restock;
// Simulate sales that reduce stock and trigger the event
inventory.ProcessSale(3); // Stock = 7, no event
inventory.ProcessSale(4); // Stock = 3, event triggered
}
}
4. Assignments to Practice Passing Data into Event Handlers
Here are three assignments to help you practice passing data into event handlers:
Easy Level:
Modify the StockChangedEventArgs
class to include the name of the person who processed the sale. Pass this information along with the old and new stock levels to the event subscribers.
Hint: Add a new property to StockChangedEventArgs
and pass the value when raising the event.
Medium Level:
Extend the program to handle multiple products. Create a dictionary in the InventoryManager
to track multiple items, each with its own stock level. Modify the event to include the product’s unique identifier along with the stock levels.
Hint: Use a Dictionary<string, int>
to track products and stock levels. Update the event data accordingly.
Difficult Level:
Make the event asynchronous. Modify the WarehouseManager
to handle the StockLow
event asynchronously. Use Task.Run
to simulate time-consuming operations in the event handler, such as reordering stock.
Hint: Use async
and await
in the event handler, and ensure that the event handling works correctly in an asynchronous environment.
Conclusion
Passing custom data into event handlers is a key technique in making event-driven systems more flexible and powerful. By using custom event arguments, you can give subscribers the context they need to make informed decisions. In this article, we’ve shown how to pass stock information in a stock management system and provided practical assignments to deepen your understanding of the topic.
Top comments (0)