Pattern Matching & Switch Expressions
Modern C# lets you ask "what shape is this value?" and branch on the answer in a single, elegant expression. Pattern matching replaces towers of nested if/else with code that reads like a decision table. In this lesson you'll learn the is operator, switch expressions, and the type, relational, property and when patterns that make them powerful.
Learn Pattern Matching & Switch Expressions in our free C# course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…
Part of the free C# course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Think of an airport security line with several lanes: "passengers with no bags here", "first class there", "anyone with liquids over 100ml step aside". Each lane is a pattern — a description of who belongs in it — and each traveller is routed to the first lane they match. A switch expression is exactly that: a list of patterns, each with an outcome, and your value walks down the lanes until one fits.
1. The is Operator & Type Patterns
The is keyword tests whether a value matches a pattern, and can capture it into a new variable at the same time. value is string s means "if value is a string, give me it as s ". You'll also use is null and is not null constantly — they read like plain English.
2. Switch Expressions
A switch expression turns a value into another value. Note the differences from the old switch statement: the value comes before the switch keyword, arms use => arrows and commas, there's no case or break , and _ is the catch-all. Arms are tested top to bottom and the first match wins — so order your relational patterns from most to least specific.
Your turn — complete the ticket-pricing switch by filling in the relational patterns.
3. when Guards
Sometimes a pattern isn't quite enough — you also need a condition. A when guard adds any boolean expression to an arm: it only matches if both the pattern and the guard are true. This keeps complex rules readable instead of nesting if s.
4. Property Patterns
Property patterns peek inside an object and match against its properties using {' '} braces: {' '} . You can match several properties at once, and combine them with type patterns. This is where pattern matching really shines — describing the exact shape of data you care about.
These switch arms are scrambled. Reorder them so the expression correctly classifies a temperature and is never unreachable.
Most-specific relational patterns come first; < 0 must precede < 15 (a value like -5 matches both), and _ is always last.
10 — o is an int, so it's captured as n (5) and doubled.
B — 80 isn't >= 90 but is >= 60, so the second arm wins.
even+ — 6 is positive and even, so the guarded arm matches.
Type patterns, property patterns and the null pattern combine into a clean, branch-free area calculator. Compare this to the if (shape is Circle) ... else if ... version you'd have written before.
Write a switch expression that maps status codes to friendly text. Mind the ordering of your relational patterns!
Practice quiz
What does 'value is string s' do?
- Converts value to a string
- Always returns true
- Tests if value is a string and captures it as s
- Compares value to the text 'string'
Answer: Tests if value is a string and captures it as s. The 'is' type pattern tests the shape and captures the matched value into a new variable s.
How do switch expression arms differ from old switch statement cases?
- They use => arrows and commas, with no case or break
- They use 'case' and 'break'
- They require a loop
- They cannot return a value
Answer: They use => arrows and commas, with no case or break. A switch expression returns a value using => arms separated by commas — no case, no break.
In a switch expression, which arm runs when several patterns could match?
- The most specific one anywhere
- All matching arms
- The last arm
- The first matching arm, top to bottom
Answer: The first matching arm, top to bottom. Arms are tested top to bottom and the first match wins, so order matters.
What does the discard pattern _ match?
- Only null
- Anything else (the default)
- Only zero
- Nothing
Answer: Anything else (the default). _ is the discard/default pattern — it matches anything not handled above and is usually placed last.
What does a 'when' guard add to a pattern arm?
- An extra boolean condition on top of the pattern
- A loop
- A type cast
- A default value
Answer: An extra boolean condition on top of the pattern. A 'when' clause adds an arbitrary boolean test; the arm matches only if both the pattern and the guard are true.
Do switch expression arms fall through like C or JavaScript cases?
- Yes, always
- Only with break
- No — exactly one arm runs, with no fall-through or break
- Only for numbers
Answer: No — exactly one arm runs, with no fall-through or break. There is no fall-through; exactly one arm (the first match) runs and its value is returned.
What does the property pattern '{ Total: > 50 }' match?
- Any object
- An object whose Total property is greater than 50
- A number equal to 50
- A list of 50 items
Answer: An object whose Total property is greater than 50. Property patterns match against an object's properties using braces; this matches when Total is over 50.
What does the compiler do if a switch expression isn't exhaustive and has no _ arm?
- Silently ignores it
- Refuses to compile entirely with no message
- Adds a default automatically
- Warns it may not handle all values (and it can throw at runtime)
Answer: Warns it may not handle all values (and it can throw at runtime). It warns the expression is non-exhaustive; adding a _ arm resolves it and prevents a runtime throw.
Which logical pattern reads as a range check for a single digit?
- 0 or 9
- >= 0 and <= 9
- not 0
- is digit
Answer: >= 0 and <= 9. Logical patterns combine with and/or/not; '>= 0 and <= 9' matches a single digit.
Why must '< 0' come before '< 15' in a relational switch expression?
- Alphabetical order
- It doesn't matter
- Because a value like -5 matches both, and the first match wins
- Negative numbers are illegal otherwise
Answer: Because a value like -5 matches both, and the first match wins. Order specific-to-general: -5 matches both, so the more specific '< 0' must come first or it becomes unreachable.