Instead of using multiple if conditions, switch statement can be used to make code more readable.
Some Facts and features of switch case:
- The switch statement does not return any value.
- The switch keyword is followed by an expression inside parentheses.
- The expression is evaluated for its value or type etc. with case label.
- Inside switch block, there are case statements.
- Each case is followed by a label.
- The label can be constant or pattern.
- The label can be either a literal value e.g. 1, 4, 7.8, true, false, tuple values etc.
- Or, it can be a data type e.g. int, float, double etc.
- Or, it can be data type followed by a variable for that type.
- Or, it can be data type followed by a variable of that type and constraint on the variable using when clause.
- Each case must end with a jump statement (break, return, throw, etc).
- The break statement is not mandatory in switch statement. Instead, you can use return or throw statement also.
- The default keyword is used for default case. It represents the case not found in other cases. It can be placed any order. It should not necessarily be the last case.
- The default case is optional.
- You can also pass delegate variable in switch expression.
In brief, a switch statement executes one matching case block. Cases can use constants or patterns. Each case must end with a jump statement (break, return, throw, etc.) to prevent fall-through. default is optional and may appear anywhere.
List of Examples
- Example. Case exact matching constant (constant pattern match)
- Example. Case of inexact match with relational operator(>,<,>=,<=) (constant pattern match)
- Example. Case of matching with not operator(constant pattern match)
- Example. Case of matching string type and its value(constant pattern match)
- Example. Case with Boolean value(constant pattern match)
- Example. Case with different datatypes(type pattern match)
- Example. Case matching value and its datatype (pattern match)
- Example. Case matching value and its datatype plus constraint on value (pattern match)
- Example. Case matching value tuple (constant match)
- Example. switch expression with lambda literal (pattern match)
- Example. switch expression with lambda literal to match value tuple
- Example. switch with delegate object, check if delegate exists
- Example. switch with delegate invoked, (constant match)
- Example. switch with delegate object (delegate type match)
Example. Case exact matching constant (constant pattern match)
class Demo
{
public void Guess(int number)
{
switch (number)
{
case 1:
Console.WriteLine("Value is 1");
Console.WriteLine("Some more statements for 1.");
break; // required
case 2:
case 3:
Console.WriteLine("Value is 2 or 3");
break; // required
default:
Console.WriteLine("Value did not match.");
break; // required
}
}
}
class Program
{
Random rand = new Random();
static void Main(string[] args)
{
Program p = new();
Demo demo = new();
demo.Guess(p.rand.Next(1, 10));
}
}
Example. Case of inexact match with relational operator(>,<,>=,<=) (constant pattern match)
class Demo
{
public void Guess(int number)
{
switch (number)
{
case >= 10:
Console.WriteLine("Greater than 10");
break;
case < 0:
Console.WriteLine("Negative");
break;
case 5:
Console.WriteLine("Exactly 5");
break;
}
}
}
class Program
{
static void Main(string[] args)
{
Program p = new();
Demo demo = new();
demo.Guess(20); // Greater than 10
demo.Guess(-2); // Negative
demo.Guess(7); // Not 5
demo.Guess(5); // Exactly 5
}
}
Example. Case of matching with not operator(constant pattern match)
class Demo
{
public void Guess(int number)
{
switch (number)
{
case not 5:
Console.WriteLine("Other than 5");
break;
case 5:
Console.WriteLine("Five");
break;
}
}
}
class Program
{
static void Main(string[] args)
{
Program p = new();
Demo demo = new();
demo.Guess(20); // Other than 5
demo.Guess(5); // Five
}
}Example. Case of matching string type and its value(constant pattern match)class Demo
{
public void Guess(string animal)
{
switch (animal)
{
case "Crow":
Console.WriteLine("Crow is a bird");
break; // required
case "Cat":
case "Dog":
Console.WriteLine("Cat or Dog");
break; // required
default:
Console.WriteLine("Not an animal.");
break; // required
}
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess("Dog");
demo.Guess("Robert");
}
} Example. Case with Boolean value(constant pattern match)class Demo
{
public void Guess(bool success)
{
switch (success)
{
case true:
Console.WriteLine("Truth is life.");
break; // required
case false:
Console.WriteLine("Life is hell for falsehood.");
break; // required
// default is optional, here not required
}
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess(false);
demo.Guess(true);
}
}
Example. Case with different datatypes(type pattern match)class Demo
{
public void Guess(object data) // boxing
{
switch (data) // data should be primitive type
{
case int:
Console.WriteLine("Integer type.");
break; // required
case float:
Console.WriteLine("Float type.");
break; // required
case double:
Console.WriteLine("Double type.");
break; // required
case bool:
Console.WriteLine("Boolean type.");
break; // required
// default is optional, here not required
}
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess(11);
demo.Guess(11.12F);
demo.Guess(11.12);
demo.Guess(true);
}
}
Example. Case matching value and its datatype (pattern match)class Demo
{
public void Guess(object data) // boxing
{
switch (data) // data should be primitive type
{
case int x:
Console.WriteLine($"Integer type value is {x}.");
break; // required
case float x:
Console.WriteLine($"Float type value is {x}.");
break; // required
case double x:
Console.WriteLine($"Double type value is {x}.");
break; // required
case bool x:
Console.WriteLine($"Boolean type value is {x}.");
break; // required
// default is optional, here not required
}
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess(11);
demo.Guess(11.12F);
demo.Guess(11.12);
demo.Guess(true);
}
}
Example. Case matching value and its datatype plus constraint on value (pattern match)class Demo
{
public void Guess(object data) // boxing
{
switch (data) // data should be primitive type
{
case int x when x + 5 > 10:
Console.WriteLine($"Integer type value is {x}.");
break; // required
case float x when x > 10.15F:
Console.WriteLine($"Float type value is {x}.");
break; // required
case double x when x > 1.0:
Console.WriteLine($"Double type value is {x}.");
break; // required
case bool x:
Console.WriteLine($"Boolean type value is {x}.");
break; // required
// default is optional, here not required
}
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess(6);
demo.Guess(1.12F);
demo.Guess(1.12);
demo.Guess(true);
}
}
Example. Case matching value tuple (constant match)class Demo
{
public void Guess((int, int) data)
{
switch (data)
{
case (1, 1):
Console.WriteLine($"Coordinate x and y are: {data.Item1} and {data.Item2}");
break;
case (2, 1):
Console.WriteLine($"Coordinate x and y are: {data.Item1} and {data.Item2}");
break;
case (1, 2):
Console.WriteLine($"Coordinate x and y are: {data.Item1} and {data.Item2}");
break;
default:
Console.WriteLine("No tuple matched!");
break;
}
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess((1, 12));
demo.Guess((1, 2));
}
}
Example. switch expression with lambda literal (pattern match)
class Demo
{
public void Guess(int input)
{
string result = input switch
{
1 => $"The output for 1 is {input + 10}",
2 => $"The output for 2 is {input + 20}",
_ => "No match found",
};
Console.WriteLine(result);
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess(1);
demo.Guess(2);
demo.Guess(3);
}
}
Example. switch expression with lambda literal to match value tupleclass Demo
{
public void Guess((int, int) input)
{
string result = input switch
{
(1, 1) => $"{input.Item1} == {input.Item2}",
(1, 2) => $"{input.Item1} < {input.Item2}",
(2, 1) => $"{input.Item1} > {input.Item2}",
_ => "No match found",
};
Console.WriteLine(result);
}
}
class Program
{
static void Main(string[] args)
{
Demo demo = new();
demo.Guess((1, 1));
demo.Guess((1, 2));
demo.Guess((3, 2));
}
}Example. switch with delegate object, check if delegate existsYou can pass a delegate variable as the switch expression.
class Demo
{
public void Test(Action d)
{
switch (d)
{
case null:
Console.WriteLine("Delegate is null");
break;
default:
Console.WriteLine("Delegate exists");
break;
}
}
}
class Program
{
Action someAction = () => Console.WriteLine("Hello");
static void Main(string[] args)
{
Program p = new();
Demo demo = new();
demo.Test(p.someAction);
}
}
Example. switch with delegate invoked, (constant match)
class Demo
{
public void Test(Func<int> d)
{
switch (d()) // invoke delegate
{
case 10:
Console.WriteLine("Ten");
break;
case > 10:
Console.WriteLine("Greater than 10");
break;
}
}
}
class Program
{
Func<int> someDelegate = () => 10;
static void Main(string[] args)
{
Program p = new();
Demo demo = new();
demo.Test(p.someDelegate);
}
}
Example. switch with delegate object (delegate type match)
class Demo
{
public void Test(Delegate d)
{
switch (d)
{
case Action:
Console.WriteLine("Action delegate");
break;
case Func<int>:
Console.WriteLine("Func<int>");
break;
default:
break;
}
}
}
class Program
{
Delegate d = (Action)(() => { });
static void Main(string[] args)
{
Program p = new();
Demo demo = new();
demo.Test(p.d);
}
}
==