Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

A custom switch case in C#

4.00/5 (8 votes)
18 Apr 2011CPOL2 min read 39.8K  
This short article will demonstrate an idea of making a custom switch case in C#
Introduction

We all know what a switch case is, henceforth there is no need for further explanation of that.
But the current one present in C# does lack certain features (at least according to me) and I am going to list them down.


Case 1: Multiple case statement problem
Consider the below:
int i = 1;
switch (i)
{
   case 0: MessageBox.Show("Hello, this is 0"); break;
   case 1:
   case 2: MessageBox.Show("Hello, this is 1 and 2 block"); break;
}

As we find that, Case 1 and 2 share the same piece of code but we need to declare two case statements for doing so. Just consider, if the case exceeds a large number….
Would not it have been handy if we have:
int i = 1;
switch (i)
{
   case 0: MessageBox.Show("Hello, this is 0"); break;
   case 1..2: MessageBox.Show("Hello, this is 1 and 2 block"); break;
}

We just have to specify the start and the end values within the ellipses(..) and the job is done.

Case 2: Accepts only certain data types

A switch expression or case label accepts only the below data types:
- Bool
- Char
- String
- Integral
- Enum
- Nullable data types

Henceforth, the following will not even compile:
double i = 1.0;
switch (i)
{
   // some case statements
}

Case 3: Does not support mixed data type

Consider the following which will happily fail:


int i = 1;
switch (i)
{
    case 0: MessageBox.Show("Hello, this is 0"); break;
    case "A":
    case "B": MessageBox.Show("Hello, this is block A and B"); break;
}


By giving the error message Cannot implicitly convert type string to int

Won’t it be nice if we have those features incorporated into the switch statement? Let us see how we can do so.



Background

I was going through an answer in Stack Overflow when I hit upon this idea of making a custom switch case. I have just tried to play around with the idea in .NET and it has been implemented here. Let’s see how it goes.



Straight to code
Let us have a class:
public class SwitchClass<T> : Dictionary<string, Func<T>>
{
  public T Execute(string key)
  {
     if (this.ContainsKey(key)) return this[key]();
            else return default(T);
  }
}

This is a generic class that inherits a dictionary object. We have a method call Execute which is again generic and it accepts a key. If a match is found, it returns the value else let us see this new stuff in action.

Case 1: Solving Multiple Case statement
Let us invoke it as under:
int result = 0;

new SwitchClass<int>
{
   { "case 1",  ()=> result = 1 },
   { "case 2..10",  ()=>result = 20 },
}.Execute("case 2..10");

MessageBox.Show(result.ToString());

The output being 20 in this case. We are specifying the case statements in the key list and the values will the returned in the Func delegate. The class is typed which is integer in this case and henceforth the return value will always be of type integer.

Case 2: Solving limited data types acceptance problem

double result = 0;
new SwitchClass<double>
{
  { "case 1",  ()=>result += 1.0 },
  { "case 2..10",  ()=>result += 20.12 },
}.Execute("case 1");
MessageBox.Show(result.ToString());

The value is 10 as expected. As we can see that our switch case accepts double here. It can accept any kind of object.

Limitation of this approach

Since it is type safe, we cannot accommodate the third limitation of the general switch statement here. But it can be done by a little bit of modification.
Let us modify our SwitchClass as under:

public class ModifiedSwitchCase : Dictionary<string, Func<object>>
{
   public void Execute(string key)
   {
            if (this.ContainsKey(key)) this[key]();
   }
}

The change is that we have removed the generic type and the Func delegate will return an object.

Case 3: Solving the mixed data type support

var result = 0;
new ModifiedSwitchCase
{
  { "case 0",  ()=> result = 10 },
  { "case A..B",  ()=> MessageBox.Show("Hello, this is block A and B") },
}.Execute("case 0");
MessageBox.Show(result.ToString());

The value will be 10 here.

Conclusion

Hope this little tip will be helpful. Comments and suggestions are welcome.
Thanks for reading.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)