DEV Community

mohamed Tayel
mohamed Tayel

Posted on

c# advanced: Pattern Matching in c#

Pattern matching in C# provides a clean, readable way to check an object’s properties and type. In this article, we’ll use an InventoryProcessor example to explore property, type, constant, and declaration patterns, helping manage inventory items based on stock levels, categories, and reorder conditions.

By the end, you’ll see how these patterns help improve code readability and make conditional logic easier to maintain.


1. Introduction to Pattern Matching in C#

Pattern matching in C# enables you to write logic based on an object’s structure and content, rather than relying only on type checks. Here, we’ll cover several types of patterns, including property, type, constant, and declaration patterns, to handle inventory items effectively.


2. Defining the Classes

Before we dive into pattern matching, let’s set up the necessary classes. We’ll use an InventoryProcessor class to process items in an inventory and decide when to reorder based on stock level and category.

Item Class

The Item class represents individual items in the inventory, each with its name, current stock, reorder level, and category.

public class Item
{
    public string Name { get; set; }
    public int Stock { get; set; }
    public int ReorderLevel { get; set; }
    public string Category { get; set; } // e.g., "Electronics", "Grocery"
}
Enter fullscreen mode Exit fullscreen mode

InventoryProcessor Class

The InventoryProcessor class checks each item using pattern matching, determining if it needs restocking based on the Stock and Category properties.

public class InventoryProcessor
{
    public void ProcessItem(Item item)
    {
        // Check if stock is below reorder level and the category is "Electronics"
        if (item is { Stock: < 10, Category: "Electronics" })
        {
            Console.WriteLine($"Reorder needed for electronic item: {item.Name}");
        }
        // Check if stock is low and item is in Grocery
        else if (item is { Stock: < 20, Category: "Grocery" })
        {
            Console.WriteLine($"Restock grocery item: {item.Name}");
        }
        else
        {
            Console.WriteLine($"Stock level is adequate for {item.Name}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Property Patterns in InventoryProcessor

The property pattern { Stock: < 10, Category: "Electronics" } lets us check two properties of Item at once, specifying that Stock should be less than 10 and Category should be "Electronics". This enables clear and targeted checks, making conditions concise and easy to understand.

4. Using Constant Patterns to Match Specific Conditions

Constant patterns match properties against fixed values like numbers or strings. For example, checking Category: "Grocery" or Stock: < 20 helps us apply specific rules for different categories, simplifying code that needs to handle various inventory categories differently.


5. Calling InventoryProcessor from Main

Now that our classes are defined, let’s see how to create and process Item instances in the Main method.

public class Program
{
    public static void Main(string[] args)
    {
        // Initialize InventoryProcessor
        var processor = new InventoryProcessor();

        // Create a few item instances
        var laptop = new Item { Name = "Laptop", Stock = 5, ReorderLevel = 10, Category = "Electronics" };
        var apple = new Item { Name = "Apple", Stock = 15, ReorderLevel = 20, Category = "Grocery" };
        var chair = new Item { Name = "Chair", Stock = 25, ReorderLevel = 5, Category = "Furniture" };

        // Process each item
        processor.ProcessItem(laptop);
        processor.ProcessItem(apple);
        processor.ProcessItem(chair);
    }
}
Enter fullscreen mode Exit fullscreen mode

When run, this code will:

  • Laptop: Trigger the reorder message for electronics due to low stock.
  • Apple: Prompt restocking for the grocery category since its stock is below the reorder level.
  • Chair: Show that stock is adequate, requiring no action.

6. Advanced Example: Combining Property and Constant Patterns

Using pattern matching, we can handle more complex conditions, like checking nested properties or combining multiple patterns. For example, if we want to apply a special rule for high-value items in a premium category, we could add further conditions.

public void ProcessHighValueItem(Item item)
{
    if (item is { Category: "Premium", Stock: > 0, ReorderLevel: < 5 })
    {
        Console.WriteLine($"High-value premium item '{item.Name}' requires immediate attention!");
    }
}
Enter fullscreen mode Exit fullscreen mode

This pattern checks that the item belongs to the "Premium" category, has a positive stock, and is below the reorder threshold, creating targeted conditions without nested if statements.


7. When to Use Pattern Matching in Inventory Processing

Pattern matching brings expressive power to C# code, especially when handling complex conditions. However, overusing patterns can lead to reduced readability. Best practices include:

  • Use property patterns for simple, direct property checks.
  • Avoid complex nesting: Too many nested conditions can make the code hard to follow.
  • Combine patterns judiciously: When multiple patterns clarify intent, combining them can reduce redundancy.

Pattern matching in InventoryProcessor makes it easy to apply complex conditions to inventory management logic without bloated code. By structuring conditions for items directly, we create readable, maintainable logic for handling inventory effectively.


This approach helps simplify inventory management in C#, showing how pattern matching can make even complex conditions easy to handle.

Top comments (0)