What is pattern matching in C# and how has it evolved?
Learn C# pattern matching from is-expressions to switch expressions, property, relational, and list patterns, with examples and interview questions and answers.
Expected Interview Answer
Pattern matching in C# is a language feature that tests a value against a shape or condition and, on a match, extracts data from it in a single concise expression. It replaces long chains of type checks, casts, and null comparisons with declarative patterns.
It started in C# 7 with type patterns and the 'is' expression plus switch statements that could match on type and deconstruct. Later versions added switch expressions (C# 8), property, tuple, and positional patterns, relational and logical patterns like '> 100' and 'and'/'or'/'not' (C# 9), and list patterns (C# 11). Together these let you match on structure, ranges, and combinations, with the compiler enforcing exhaustiveness on switch expressions.
- Removes verbose type-check-then-cast boilerplate
- Makes conditional logic read declaratively
- Deconstructs objects and tuples inline
- Compiler warns on non-exhaustive switch expressions
- Combines conditions with and/or/not clearly
- Handles null safely with constant and 'not null' patterns
AI Mentor Explanation
A wicketkeeper reads the incoming ball by its shape at once: length, line, and spin all matched in a single glance, then he moves and gathers accordingly. Pattern matching works the same way, testing a value's type and shape together and extracting its data in one motion rather than checking each property with a separate, clumsy appeal.
Step-by-Step Explanation
Step 1
Type pattern with 'is'
Use 'if (obj is Circle c)' to test the type and bind a typed variable in one step, no explicit cast needed.
Step 2
Switch on patterns
A switch expression matches each arm against a pattern, returning a value: 'shape switch { Circle c => ..., Square s => ... }'.
Step 3
Add property patterns
Match on member values inline: '{ Radius: > 10 }' matches a shape whose Radius exceeds 10.
Step 4
Combine with logical patterns
Use 'and', 'or', 'not' and relational patterns: 'int and > 0 and < 100' or 'not null'.
Step 5
Ensure exhaustiveness
Add a discard arm '_ =>' so the switch expression covers every case and the compiler stops warning.
What Interviewer Expects
- Knowing 'is' pattern binds a typed variable without a cast
- Difference between switch statement and switch expression
- Awareness of property, tuple, and relational patterns
- Understanding exhaustiveness and the discard pattern
- Rough timeline of features across C# 7 to C# 11
Common Mistakes
- Still casting after an 'is' check instead of using the bound variable
- Forgetting a default arm and hitting a non-exhaustive switch
- Confusing switch statements with switch expressions
- Overusing patterns where a simple polymorphic method is cleaner
- Not knowing 'not null' handles null checks
Best Answer (HR Friendly)
“Pattern matching is a C# feature that lets you check what kind of value you have and pull data out of it in one clean line, instead of many nested checks and casts. It has grown over several C# versions to match types, property ranges, and combinations, making conditional code much easier to read.”
Code Example
public static string Describe(object value) => value switch
{
null => "nothing",
int n and > 0 and < 100 => $"small int {n}",
int n => $"int {n}",
string { Length: > 0 } s => $"text: {s}",
Circle { Radius: > 10 } => "big circle",
Circle c => $"circle r={c.Radius}",
_ => "unknown"
};Follow-up Questions
- What is the difference between a switch statement and a switch expression?
- How do relational and logical patterns work in C# 9?
- What are list patterns introduced in C# 11?
- How does the compiler enforce exhaustiveness?
- When would you prefer polymorphism over a switch on type?
MCQ Practice
1. What does the 'is' type pattern do beyond checking the type?
The 'is' pattern tests the type and, on a match, binds a strongly typed variable so no separate cast is needed.
2. Which C# version introduced relational and logical (and/or/not) patterns?
C# 9 added relational patterns like '> 100' and logical combinators 'and', 'or', and 'not'.
3. What does a discard arm '_ =>' provide in a switch expression?
The discard arm matches anything not covered, making the switch exhaustive and silencing the compiler warning.
Flash Cards
What does 'obj is Circle c' do? — Tests that obj is a Circle and binds it to typed variable c, no cast required.
Switch statement vs switch expression? — The statement executes cases; the expression returns a value and each arm uses '=>'.
What is a property pattern? — Matches on member values inline, e.g. '{ Radius: > 10 }'.
Which version added list patterns? — C# 11 added list patterns like '[1, 2, ..]'.