Pattern Matching
Pattern matching is a modern C# feature that allows you to check whether a value matches a specific type, value, property, relationship, or structure.
It makes conditional logic easier to read and is especially useful when working with objects, APIs, validation, business rules, and different types of data.
What is Pattern Matching?
Pattern matching means comparing a value against a pattern and executing code when the value matches that pattern.
C# provides several types of patterns including type patterns, constant patterns, relational patterns, logical patterns, property patterns, positional patterns, tuple patterns, and list patterns.
Basic Syntax
if (value is pattern)
{
// Code executes when pattern matches
}
1. Type Pattern with is
The is keyword can check whether an object is of
a particular type.
using System;
object value = "CIIT Training Institute";
if (value is string)
{
Console.WriteLine("The value is a string.");
}
Output
The value is a string.
2. Declaration Pattern
A declaration pattern checks the type and also creates a variable containing the converted value.
using System;
object value = "C# Programming";
if (value is string text)
{
Console.WriteLine(text);
}
Output
C# Programming
Here, value is string text checks the type and
creates the variable text.
3. Constant Pattern
A constant pattern checks whether a value is equal to a specific constant value.
using System;
int status = 200;
if (status is 200)
{
Console.WriteLine("Request successful.");
}
Output
Request successful.
4. Relational Patterns
Relational patterns allow you to compare a value using operators
such as >, <, >=,
and <=.
using System;
int marks = 85;
if (marks is >= 75)
{
Console.WriteLine("Distinction");
}
Output
Distinction
Range Example
using System;
int age = 25;
if (age is >= 18 and <= 60)
{
Console.WriteLine("Working age group.");
}
5. Logical Patterns
Logical patterns combine multiple conditions using
and, or, and not.
and Pattern
using System;
int marks = 82;
if (marks is >= 75 and <= 100)
{
Console.WriteLine("Excellent result.");
}
or Pattern
using System;
int day = 6;
if (day is 6 or 7)
{
Console.WriteLine("Weekend");
}
not Pattern
using System;
string? name = null;
if (name is not null)
{
Console.WriteLine(name);
}
6. Property Pattern
Property patterns allow you to check the properties of an object directly without manually accessing each property in separate conditions.
using System;
class Student
{
public string Name { get; set; }
public int Marks { get; set; }
}
class Program
{
static void Main()
{
Student student = new Student
{
Name = "Rahul",
Marks = 88
};
if (student is { Marks: >= 75 })
{
Console.WriteLine("Student passed with distinction.");
}
}
}
Output
Student passed with distinction.
7. Combining Type and Property Patterns
Type and property patterns can be combined to check both the object's type and its property values.
using System;
class Student
{
public string Name { get; set; }
public int Marks { get; set; }
}
class Program
{
static void Main()
{
Student student = new Student
{
Name = "Priya",
Marks = 92
};
if (student is Student { Marks: >= 90 } s)
{
Console.WriteLine(
$"{s.Name} achieved an excellent score."
);
}
}
}
Output
Priya achieved an excellent score.
8. Pattern Matching with switch
Pattern matching becomes especially powerful when used with
switch.
using System;
object value = 100;
switch (value)
{
case int number:
Console.WriteLine($"Integer: {number}");
break;
case string text:
Console.WriteLine($"String: {text}");
break;
default:
Console.WriteLine("Unknown type");
break;
}
Output
Integer: 100
9. Switch Expression
A switch expression is a shorter and more expressive way to return a value based on a pattern.
using System;
int marks = 82;
string grade = marks switch
{
>= 90 => "A+",
>= 75 => "A",
>= 60 => "B",
>= 50 => "C",
_ => "Fail"
};
Console.WriteLine(grade);
Output
A
10. Pattern Matching with when
The when keyword allows an additional condition
to be applied after a pattern matches.
using System;
int marks = 85;
string result = marks switch
{
int score when score >= 75 => "Distinction",
int score when score >= 50 => "Pass",
_ => "Fail"
};
Console.WriteLine(result);
Output
Distinction
11. Positional Pattern
Positional patterns can be used with types that expose positional data, such as records and tuples.
using System;
var student = ("Rahul", 85);
if (student is ("Rahul", >= 75))
{
Console.WriteLine("Rahul passed with good marks.");
}
Output
Rahul passed with good marks.
12. Tuple Pattern
Tuple patterns are useful when multiple values need to be checked together.
using System;
int marks = 85;
bool attendance = true;
string result = (marks, attendance) switch
{
(>= 75, true) => "Eligible for placement support",
(>= 50, true) => "Eligible for final assessment",
_ => "Needs improvement"
};
Console.WriteLine(result);
Output
Eligible for placement support
13. List Patterns
List patterns allow modern C# applications to match the structure and contents of arrays or collections.
using System;
int[] numbers = { 1, 2, 3 };
if (numbers is [1, 2, 3])
{
Console.WriteLine("Exact sequence matched.");
}
Output
Exact sequence matched.
Discard Pattern in Lists
using System;
int[] numbers = { 10, 20, 30, 40 };
if (numbers is [10, ..])
{
Console.WriteLine("List starts with 10.");
}
14. Example: API Response 🤓🌍
Pattern matching is useful when an application receives different types of responses and needs to process them differently.
using System;
object response = 200;
string message = response switch
{
200 => "Request completed successfully.",
400 => "Bad request.",
401 => "Unauthorized request.",
404 => "Resource not found.",
>= 500 => "Server error.",
_ => "Unknown response."
};
Console.WriteLine(message);
Output
Request completed successfully.
Traditional Conditions vs Pattern Matching
| Traditional Approach | Pattern Matching |
|---|---|
| Multiple if conditions | Clear pattern-based conditions |
| Manual type casting | Type checking and variable creation together |
| Long conditional logic | Concise switch expressions |
| Separate property checks | Property patterns |
| Complex range conditions | Relational and logical patterns |
When Should You Use Pattern Matching?
- When checking the type of an object.
- When validating values against ranges.
- When multiple conditions depend on the same value.
- When processing different object types.
- When working with API responses.
- When implementing business rules.
- When switch logic becomes complex.
- When working with modern C# records and collections.
Common Mistakes
- Using complicated patterns when a simple condition is enough.
-
Forgetting the discard pattern
_in switch expressions. - Writing overlapping switch patterns in the wrong order.
- Mixing too many conditions into a single pattern.
- Using pattern matching without understanding the underlying data type.
Best Practices
- Keep patterns simple and readable.
- Use switch expressions when they improve clarity.
- Use property patterns for object validation.
- Use relational patterns for ranges.
- Use logical patterns instead of deeply nested conditions.
- Keep the most specific patterns before general patterns.
- Use the discard pattern for unexpected or default cases.
Interview Questions
- What is pattern matching in C#?
- What is the difference between
isandas? - What is a declaration pattern?
- What are relational patterns?
- Explain
and,or, andnotpatterns. - What is a property pattern?
- What is a switch expression?
- What is the purpose of the discard pattern
_? - What are positional and tuple patterns?
- What are list patterns in modern C#?
Practice Programs
- Create a program that checks whether an object contains a string, integer, or double value.
- Create a grade calculator using relational patterns.
- Create a switch expression for HTTP status codes.
- Create a Student class and validate its properties using a property pattern.
- Create a program using tuple patterns to evaluate marks and attendance.
- Create a program that checks an integer array using a list pattern.
Summary
- Pattern matching provides a clean way to check values and objects.
-
The
iskeyword can perform type and declaration matching. - Constant patterns compare values directly.
- Relational patterns handle ranges and comparisons.
-
Logical patterns combine conditions using
and,or, andnot. - Property patterns validate object properties.
- Switch expressions make conditional result selection concise.
- Positional, tuple, and list patterns support structured data matching.
- Pattern matching is an important modern C# feature for clean, maintainable application code.