Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

C# Dictionary

  1. Home
  2. C# Dictionary
  3. switch Statement / switch Expression (C#)

switch Statement / switch Expression (C#)

The switch statement provides a concise way to write multi-branch conditionals. C# 8 and later also introduced the switch expression. You can use pattern matching on strings, enums, types, and more, replacing long chains of if / else if with cleaner, more readable code.

Syntax

switch (variable or expression) {
	case value1:
		// Executed when the value matches value1.
		break;
	case value2:
		// Executed when the value matches value2.
		break;
	default:
		// Executed when no case matches.
		break;
}

// Multiple values can be grouped into a single case.
switch (variable) {
	case value1:
	case value2:
		// Executed when the value matches either value1 or value2.
		break;
	default:
		break;
}

// Use goto case to explicitly fall through to another case.
switch (variable) {
	case value1:
		// After processing, jumps to the value2 case.
		goto case value2;
	case value2:
		// Executed whether reached via goto from value1, or matched directly.
		break;
}

var result = variable switch {
	value1 => returnValue1,
	value2 => returnValue2,
	_ => defaultValue
};

// A when guard adds an extra condition to a pattern arm.
var result = variable switch {
	type v when condition => returnValue,
	_ => defaultValue
};

switch statement vs. switch expression

Featureswitch statementswitch expression (C# 8+)
Syntaxcase / break / defaultArrow (=>) returns a value.
Use caseExecuting multiple statements per branch.Selecting and returning a single value.
Fall-throughExplicit via goto case.Not supported — each arm is independent.
Default equivalentdefault:_ => (wildcard)
when guardcase value when condition:value when condition =>
Exhaustiveness checkNone.The compiler may warn about unhandled cases.

Sample Code

SwitchBasic.cs
using System;

class SwitchBasic {
	static void Main() {

		// Determines the skill of a member by name.
		string name = "member_3";

		switch (name) {
			case "member_2":
				Console.WriteLine(name + " handles skill_a.");
				break;
			case "member_3":
				Console.WriteLine(name + " handles skill_b."); // This branch executes.
				break;
			case "member_4":
				Console.WriteLine(name + " handles skill_c.");
				break;
			default:
				Console.WriteLine(name + "'s skill is unknown.");
				break;
		}

		string member = "member_4";

		switch (member) {
			case "member_2":
			case "member_3":
			case "member_4":
				Console.WriteLine(member + " is a Group A member."); // This branch executes.
				break;
			case "member_5":
				Console.WriteLine(member + " is a Group B member.");
				break;
			default:
				Console.WriteLine(member + "'s group is unknown.");
				break;
		}

		// Transfers control from one case to another.
		string level = "S";

		switch (level) {
			case "S":
				Console.WriteLine("Recognized as Level S.");
				goto case "A"; // Jumps to the A case.
			case "A":
				Console.WriteLine("Authorized for advanced tasks."); // Executed for both S and A.
				break;
			case "B":
				Console.WriteLine("Capable of handling standard tasks.");
				break;
			default:
				Console.WriteLine("No level has been assigned.");
				break;
		}
	}
}

This produces the following output:

dotnet script SwitchBasic.cs
member_3 handles skill_b.
member_4 is a Group A member.
Recognized as Level S.
Authorized for advanced tasks.
SwitchEnum.cs
using System;

// An enum representing skill types.
enum SkillType {
	Analysis, // Data analysis
	Planning, // Project planning
	Design, // System design
	Review, // Code review
	Unknown // Unknown
}

class SwitchEnum {
	static void Main() {

		SkillType type = SkillType.Design;

		switch (type) {
			case SkillType.Analysis:
				Console.WriteLine("Specializes in data collection and analysis.");
				break;
			case SkillType.Planning:
				Console.WriteLine("Handles project planning.");
				break;
			case SkillType.Design:
				Console.WriteLine("Handles system design."); // This branch executes.
				break;
			case SkillType.Review:
				Console.WriteLine("Handles deliverable reviews.");
				break;
			default:
				Console.WriteLine("Skill is unknown.");
				break;
		}

		SkillType[] types = {
			SkillType.Analysis,
			SkillType.Review,
			SkillType.Unknown
		};

		foreach (SkillType t in types) {
			string description = t switch {
				SkillType.Analysis => "A fundamental data analysis skill.",
				SkillType.Planning => "A project planning skill.",
				SkillType.Design => "The foundation of system design.",
				SkillType.Review => "A skill for reviewing deliverables.",
				_ => "Skill is unknown."
			};
			Console.WriteLine(t + ": " + description);
		}
	}
}

This produces the following output:

dotnet script SwitchEnum.cs
Handles system design.
Analysis: A fundamental data analysis skill.
Review: A skill for reviewing deliverables.
Unknown: Skill is unknown.
SwitchExpression.cs
using System;

// Base class for workers.
class Worker {
	public string Name { get; set; }
	public Worker(string name) { Name = name; }
}

// Subclass for skilled workers.
class SkilledWorker : Worker {
	public int Score { get; set; }
	public SkilledWorker(string name, int score) : base(name) {
		Score = score;
	}
}

// Class representing a task item.
class TaskItem : Worker {
	public string Level { get; set; }
	public TaskItem(string name, string level) : base(name) {
		Level = level;
	}
}

class SwitchExpression {
	static void Main() {

		// Classifies entities as workers, tasks, or other types.
		object[] entities = {
			new SkilledWorker("member_2", 1200),
			new SkilledWorker("member_1", 8500),
			new TaskItem("item_b", "S"),
			new TaskItem("item_d", "S"),
			"item_c (unclassified)"
		};

		foreach (object entity in entities) {
			string status = entity switch {
				// SkilledWorker with score above 8000 is a Level S candidate.
				SkilledWorker s when s.Score > 8000
					=> s.Name + " is a Level S candidate (score: " + s.Score + ").",
				// Any other SkilledWorker.
				SkilledWorker s
					=> s.Name + " is a worker (score: " + s.Score + ").",
				// Level S task item.
				TaskItem c when c.Level == "S"
					=> c.Name + " is a Level S task.",
				// Any other task item.
				TaskItem c
					=> c.Name + " is a " + c.Level + " task.",
				// String or any other unrecognized type.
				string s
					=> s + " (unknown entity)",
				// Fallback for all remaining types.
				_ => "Unknown entity."
			};
			Console.WriteLine(status);
		}

		Console.WriteLine();
		string[] levels = { "S", "A", "B", "C", "D" };

		foreach (string level in levels) {
			int allowance = level switch {
				"S" => 500000,
				"A" => 200000,
				"B" => 100000,
				"C" => 50000,
				_ => 20000 // Default value for D and below.
			};
			Console.WriteLine("Level " + level + " monthly allowance: " + allowance + " yen");
		}
	}
}

This produces the following output:

dotnet script SwitchExpression.cs
member_2 is a worker (score: 1200).
member_1 is a Level S candidate (score: 8500).
item_b is a Level S task.
item_d is a Level S task.
item_c (unclassified) (unknown entity)

Level S monthly allowance: 500000 yen
Level A monthly allowance: 200000 yen
Level B monthly allowance: 100000 yen
Level C monthly allowance: 50000 yen
Level D monthly allowance: 20000 yen

Common Mistakes

Forgetting break and getting a compile error

In C#, omitting break (or return / throw / goto case) at the end of a case causes a compile error. Unlike C or Java, implicit fall-through is not allowed.

switch (value) {
	case 1:
		Console.WriteLine("one");
		// No break — compile error CS0163.
	case 2:
		Console.WriteLine("two");
		break;
}

Omitting _ (wildcard) in a switch expression

If a switch expression does not cover all possible cases, the compiler issues a warning. For non-enum types, always include _ (wildcard) to handle unexpected values.

string label = value switch {
	1 => "one",
	2 => "two",
	_ => "other" // Do not omit this.
};

Overview

The switch statement in C# is the traditional multi-branch construct. Each case specifies a value to match, and every branch must end with break, return, or throw. In C#, implicit fall-through — omitting break to let execution continue into the next case — is a compile error. To intentionally transfer control to another case, write goto case value explicitly.

The switch expression, introduced in C# 8, provides a compact way to select and return a value from multiple options. Each arm is separated by an arrow (=>), and the wildcard (_) specifies the default value. Adding a when guard to an arm lets you combine type and value conditions in a single expression. The compiler checks that all possible cases are handled, so omissions are caught early.

For type-based pattern matching, see also is / as / Pattern Matching. For simple true/false branching, see if / else.

If you find any errors or copyright issues, please .