Master C# Programming From Scratch

Clear, interactive, and structured coding lessons designed for absolute beginners.

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.

Key Idea: Pattern matching allows you to ask questions about data in a clean and readable way instead of writing multiple type checks and casts.

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

C#
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.

C#
using System;
 
object value = "CIIT Training Institute";

if (value is string)
{
    Console.WriteLine("The value is a string.");
}

Output

Output
The value is a string.

2. Declaration Pattern

A declaration pattern checks the type and also creates a variable containing the converted value.

C#
using System;
 
object value = "C# Programming";

if (value is string text)
{
    Console.WriteLine(text);
}

Output

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.

C#
using System;
 
int status = 200;

if (status is 200)
{
    Console.WriteLine("Request successful.");
}

Output

Output
Request successful.

4. Relational Patterns

Relational patterns allow you to compare a value using operators such as >, <, >=, and <=.

C#
using System;
 
int marks = 85;

if (marks is >= 75)
{
    Console.WriteLine("Distinction");
}

Output

Output
Distinction

Range Example

C#
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

C#
using System;
int marks = 82;

if (marks is >= 75 and <= 100)
{
    Console.WriteLine("Excellent result.");
}

or Pattern

C#
using System;
int day = 6;

if (day is 6 or 7)
{
    Console.WriteLine("Weekend");
}

not Pattern

C#
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.

C#
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

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.

C#
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

Output
Priya achieved an excellent score.

8. Pattern Matching with switch

Pattern matching becomes especially powerful when used with switch.

C#
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

Output
Integer: 100

9. Switch Expression

A switch expression is a shorter and more expressive way to return a value based on a pattern.

C#
using System;
 
int marks = 82;

string grade = marks switch
{
    >= 90 => "A+",
    >= 75 => "A",
    >= 60 => "B",
    >= 50 => "C",
    _ => "Fail"
};

Console.WriteLine(grade);

Output

Output
A

10. Pattern Matching with when

The when keyword allows an additional condition to be applied after a pattern matches.

C#
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

Output
Distinction

11. Positional Pattern

Positional patterns can be used with types that expose positional data, such as records and tuples.

C#
using System;
 var student = ("Rahul", 85);

if (student is ("Rahul", >= 75))
{
    Console.WriteLine("Rahul passed with good marks.");
}

Output

Output
Rahul passed with good marks.

12. Tuple Pattern

Tuple patterns are useful when multiple values need to be checked together.

C#
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

Output
Eligible for placement support

13. List Patterns

List patterns allow modern C# applications to match the structure and contents of arrays or collections.

C#
using System;
 
int[] numbers = { 1, 2, 3 };

if (numbers is [1, 2, 3])
{
    Console.WriteLine("Exact sequence matched.");
}

Output

Output
Exact sequence matched.

Discard Pattern in Lists

C#
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.

C#
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

Output
Request completed successfully.
CIIT Practical Point: Pattern matching is commonly useful in ASP.NET Core applications for processing API responses, validating models, checking object types, handling business rules, and simplifying conditional logic.

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

  1. What is pattern matching in C#?
  2. What is the difference between is and as?
  3. What is a declaration pattern?
  4. What are relational patterns?
  5. Explain and, or, and not patterns.
  6. What is a property pattern?
  7. What is a switch expression?
  8. What is the purpose of the discard pattern _?
  9. What are positional and tuple patterns?
  10. What are list patterns in modern C#?

Practice Programs

  1. Create a program that checks whether an object contains a string, integer, or double value.
  2. Create a grade calculator using relational patterns.
  3. Create a switch expression for HTTP status codes.
  4. Create a Student class and validate its properties using a property pattern.
  5. Create a program using tuple patterns to evaluate marks and attendance.
  6. 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 is keyword can perform type and declaration matching.
  • Constant patterns compare values directly.
  • Relational patterns handle ranges and comparisons.
  • Logical patterns combine conditions using and, or, and not.
  • 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.