Skip to main content

Fixing Multiple Switch Case Problem in C#

 In this Chapter we will see how we can fix growing switch case which cause code maintainability issue

In our development projects we may have below situation where switch cases increase with time and getting difficult to maintain

Let’s understand problem

using System;

class Program
{
static void ProcessOrder(string orderType)
{
switch (orderType)
{
case "NEW_ORDER":
Console.WriteLine("Processing new order.");
// New order logic here
break;

case "CANCEL_ORDER":
Console.WriteLine("Cancelling order.");
// Cancel order logic here
break;

case "SHIPPING":
Console.WriteLine("Shipping order.");
// Shipping logic here
break;

case "DELIVERED":
Console.WriteLine("Order delivered.");
// Delivered logic here
break;

default:
Console.WriteLine("Unknown order type.");
break;
}
}

static void Main(string[] args)
{
ProcessOrder("NEW_ORDER");
}
}

1. Difficulty in Maintenance:

When we add new cases to a switch, we must need to update code and number of lines in single function will increase and then this will be difficult to maintain.

2. Breaking SOLID Principles:

The Single Responsibility Principle (SRP) and Open/Closed Principle (OCP) from SOLID design guidelines are difficult to follow with large switch statements. These principles state that:

A class should have one reason to change (SRP), and
A class should be open for extension, but closed for modification (OCP).
If you modify a switch statement by adding a new case, you’re violating both principles.

3. Code Quality in SonarQube

When we have such bad code and number of lines will increase this will caught by SonarQube (in devops pipeline )and will break build due to high complexity in functions. in that case we need to break this code.

4. Code Readability and Testability:

large switch statement can make the code harder to read and test. Each case inside the switch block can contain multiple lines of code, including business logic, side effects, and error handling. This complexity makes unit testing difficult because it’s harder to isolate the individual behaviors tied to each case.

Solution Using Dictionary

we will replace the switch statement with a Dictionary where each key represents an order type, and the value is a delegate or a method that handles the logic for that order type.

Consider code below

using System;
using System.Collections.Generic;

class Program
{
// Define methods for each order type
static void NewOrder()
{
Console.WriteLine("Processing new order.");
// New order logic here
}

static void CancelOrder()
{
Console.WriteLine("Cancelling order.");
// Cancel order logic here
}

static void Shipping()
{
Console.WriteLine("Shipping order.");
// Shipping logic here
}

static void Delivered()
{
Console.WriteLine("Order delivered.");
// Delivered logic here
}

static void UnknownOrder()
{
Console.WriteLine("Unknown order type.");
}


}

Here we are defining Action methods those need to execute on switch cases

Defining Dictionary Code for switch case.

static void Main(string[] args)
{
// Define a dictionary mapping order types to their corresponding methods
Dictionary<string, Action> orderActions = new Dictionary<string, Action>
{
{ "NEW_ORDER", NewOrder },
{ "CANCEL_ORDER", CancelOrder },
{ "SHIPPING", Shipping },
{ "DELIVERED", Delivered }
};

// Example Usage
ProcessOrder(orderActions, "NEW_ORDER");
ProcessOrder(orderActions, "CANCEL_ORDER");
ProcessOrder(orderActions, "UNKNOWN_ORDER");
}

static void ProcessOrder(Dictionary<string, Action> orderActions, string orderType)
{
// Check if the order type exists in the dictionary and execute the corresponding action
if (orderActions.ContainsKey(orderType))
{
orderActions[orderType](); // Call the appropriate method
}
else
{
UnknownOrder(); // Default behavior for unknown order types
}
}

Details of code

  1. Dictionary of Actions: A Dictionary<string, Action> is used to map order types (the string keys) to corresponding methods (the Action values). The Action delegate in C# represents a method that doesn’t return a value (i.e., a void method).
  2. Processing Orders: In the ProcessOrder() method, we check if the order type exists in the dictionary using ContainsKey(). If it exists, we invoke the corresponding action method. If the order type doesn’t exist, the UnknownOrder() method is called.

Benefits:

  1. Scalability: You can easily add new order types by simply adding new methods and updating the dictionary. No need to modify complex switch statements.

2. Readability and Maintainability: The code is more organized, and each order type is handled by a dedicated method.

I have posted another article to fix multiple If-else using Chain of responsibility pattern. have a look and enjoy

#dotnet, #csharp, #coding, #design

Happy coding Thanks

Comments

Popular posts from this blog

Design Application using Clean Architecture

  Clean Architecture , introduced by  Robert C. Martin   (Uncle Bob), aims to create systems that are: Independent of frameworks Testable Independent of UI Independent of database Independent of any external agency Clean Architecture emphasizes separating the concerns of different parts of the system and ensuring that each part has a clear responsibility. .NET clean architecture as a development approach, available in a layered form to reduce dependency. The architecture consists of several layers, each with a specific role and dependencies that flow in one direction: from the outer layers to the inner layers. Inner most Layer is independent to its outer layer, means inner most layer does not have any references, it builds and stand independently. Dependency Rule The core principle of Clean Architecture is the  Dependency Rule , which states that source code dependencies can only point inward.  This means: Nothing in inner circle can depend on anything in an out...

How to Earn online from Medium.com

  As freelancer I started writing on medium (Tech blogs) from  Aug 2024   but I was already writing tech blogs on c-sharpcorner.com “The purpose of this post is to encourage new writers by helping them understand how they can earn as freelancers.” “Medium is a great platform for writers. When I started writing, I had no idea that I would reach the $100 benchmark in just four months. Now, I’m feeling self-inspired, as it has become a valuable source of income as a freelancer.” AUG 2024 ( $0 ) It was just beginning, and I posted 4 articles and had only few views 455 and 165 reads. During this time, I was learning about medium rules for writers and partner program. It will take some time to understand over all process. SEP 2024 ($6) As I started writing and I was getting few cents on Aug 2024, I posted 8 more articles in SEP, and it was good month because my blogs were getting noticed and I started getting claps etc. “This month, I went from $0 to $6, which was an achievemen...

Fixing High CPU Usage in .NET Core using Parallelism

  We will fix problem occurs due to incorrect use Parallelism in .NET Core To increase application performance sometimes we use process task or work extensively in Parallel and that may lead performance issue. When we do code, we should understand our requirement very carefully along with hardware resources those we have. We should code like that there should be less CPU usage and server should work without issues. In .NET Core, when you’re using parallelism (like Parallel.For, Task.WhenAll, or Task.Run), you might encounter performance issues if the number of concurrent threads or tasks exceeds what your system can efficiently handle. A common issue is high CPU usage or resource contention, which can degrade overall performance, cause excessive context switching, and even lead to thread starvation or deadlocks. Non members can access from here Effective Parallelism Strategies to Mitigate High CPU Usage in .NET Core We will fix problem occurs due to incorrect use Parallelism in .NE...