Pattern Matching

Back

Loading concept...

🎯 C# Pattern Matching: The Shape-Sorting Superpower

Imagine you have a magic sorting hat that can look at ANY object and instantly know exactly what it is, what’s inside it, and where it belongs. That’s pattern matching!


🌟 The Big Picture

Think of pattern matching like a super-smart mail sorter. When a package arrives:

  • It checks the shape (Is it a box? An envelope?)
  • It peeks at the label (Who sent it? What’s inside?)
  • It reads the address (Where does it go?)

C# pattern matching does exactly this with your data!


📚 What We’ll Learn

graph TD A["🎁 Pattern Matching"] --> B["📦 Type Patterns"] A --> C["🏷️ Property Patterns"] A --> D["📍 Position Patterns"] A --> E["📋 List Patterns"] A --> F["🔢 Relational Patterns"] A --> G["🏗️ Object Inits"] A --> H["👻 Anonymous Types"]

1️⃣ Pattern Matching Introduction

What Is It?

Pattern matching is like playing “Guess What’s In The Box”:

  • You have a mystery object
  • You ask smart questions about it
  • Based on answers, you do different things

The Old Way vs The New Way

Old way (checking type manually):

if (animal is Dog)
{
    Dog d = (Dog)animal;
    d.Bark();
}

New way (pattern matching magic):

if (animal is Dog d)
{
    d.Bark();
}

One line does what took three! ✨

Where Can You Use It?

  • is expressions
  • switch statements
  • switch expressions

2️⃣ Type and Declaration Patterns

The Type Pattern

This asks: “Are you THIS type of thing?”

Think of it like sorting toys:

  • “Is this a LEGO piece?” → Put in LEGO box
  • “Is this a doll?” → Put in doll box
object mystery = "Hello World";

if (mystery is string)
{
    Console.WriteLine("It's text!");
}

The Declaration Pattern

This does TWO things at once:

  1. Checks the type
  2. Creates a new variable!

Like saying: “If this IS a dog, call it ‘buddy’”

object mystery = 42;

if (mystery is int number)
{
    // 'number' is ready to use!
    Console.WriteLine(number * 2);  // 84
}

Using in Switch

string Describe(object obj) => obj switch
{
    int n    => quot;Number: {n}",
    string s => quot;Text: {s}",
    bool b   => quot;True/False: {b}",
    null     => "Nothing here!",
    _        => "Mystery object"
};

The _ is like saying “everything else”.


3️⃣ Property Patterns

The Idea

Property patterns let you peek INSIDE objects. Like asking:

  • “Is this a person AND are they older than 18?”
  • “Is this a car AND is it red?”

Basic Example

Imagine a Person:

record Person(string Name, int Age);

Now match on properties:

var person = new Person("Alex", 25);

if (person is { Age: 25 })
{
    Console.WriteLine("They're 25!");
}

Nested Properties

You can go deeper!

record Address(string City);
record Person(string Name, Address Home);

var alex = new Person("Alex",
    new Address("Paris"));

if (alex is { Home: { City: "Paris" } })
{
    Console.WriteLine("Parisian!");
}

// Shorter syntax:
if (alex is { Home.City: "Paris" })
{
    Console.WriteLine("Still Parisian!");
}

Combining Patterns

string GetDiscount(Person p) => p switch
{
    { Age: < 12 }         => "Kids: 50% off",
    { Age: >= 65 }        => "Seniors: 30% off",
    { Name: "VIP" }       => "VIP: 20% off",
    _                     => "Standard price"
};

4️⃣ Positional Patterns

What Are They?

When objects can “break apart” into pieces, you can match those pieces by POSITION.

Like unpacking a gift box layer by layer!

With Tuples

Tuples are perfect for this:

var point = (3, 4);

string location = point switch
{
    (0, 0) => "At the center!",
    (0, _) => "On the Y-axis",
    (_, 0) => "On the X-axis",
    (_, _) => "Somewhere else"
};

The _ means “I don’t care about this value”.

With Deconstruct

Any class with Deconstruct works:

record Point(int X, int Y);

var p = new Point(5, 10);

if (p is (5, 10))
{
    Console.WriteLine("Found it!");
}

Combining with Property Patterns

record Rectangle(Point TopLeft, Point Size);

var rect = new Rectangle(
    new Point(0, 0),
    new Point(100, 50)
);

if (rect is (_, (100, _)))
{
    Console.WriteLine("Width is 100!");
}

5️⃣ List and Relational Patterns

List Patterns (C# 11+)

Match arrays and lists by their content!

Match exact elements:

int[] nums = { 1, 2, 3 };

if (nums is [1, 2, 3])
{
    Console.WriteLine("Perfect match!");
}

Match first and last:

if (nums is [1, .., 3])
{
    // Starts with 1, ends with 3
    // '..' means "zero or more items"
}

Capture middle elements:

if (nums is [1, .. var middle, 3])
{
    // middle = [2]
}

Match length:

if (nums is [_, _, _])
{
    Console.WriteLine("Exactly 3 items!");
}

Relational Patterns

Compare with <, >, <=, >=:

string Grade(int score) => score switch
{
    >= 90 => "A - Excellent!",
    >= 80 => "B - Great!",
    >= 70 => "C - Good",
    >= 60 => "D - Pass",
    _     => "F - Try again"
};

Logical Patterns

Combine with and, or, not:

string Describe(int n) => n switch
{
    > 0 and < 10  => "Single digit positive",
    >= 10 and < 100 => "Two digits",
    < 0 or > 1000 => "Out of range",
    not 42        => "Not the answer",
    42            => "The answer!"
};

6️⃣ Object and Collection Initializers

Object Initializers

Create and set up objects in ONE step!

Without initializer:

var person = new Person();
person.Name = "Alex";
person.Age = 25;

With initializer:

var person = new Person
{
    Name = "Alex",
    Age = 25
};

Much cleaner! ✨

Nested Object Initializers

var student = new Student
{
    Name = "Alex",
    Address = new Address
    {
        City = "Paris",
        Country = "France"
    }
};

Collection Initializers

Create lists with items instantly:

var numbers = new List<int> { 1, 2, 3, 4, 5 };

var people = new List<Person>
{
    new Person { Name = "Alex" },
    new Person { Name = "Sam" }
};

Dictionary Initializers

var scores = new Dictionary<string, int>
{
    ["Alex"] = 95,
    ["Sam"] = 88,
    ["Jordan"] = 92
};

With Target-Typed New

Even shorter in C# 9+:

List<int> nums = new() { 1, 2, 3 };
Person p = new() { Name = "Alex" };

7️⃣ Anonymous Types

What Are They?

Quick, throwaway objects without writing a class!

Like making a sticky note instead of a formal document.

Creating Anonymous Types

var person = new
{
    Name = "Alex",
    Age = 25
};

Console.WriteLine(person.Name);  // Alex
Console.WriteLine(person.Age);   // 25

Key Points

  • Read-only: You can’t change values after creation
  • Type-safe: The compiler knows the properties
  • Local use: Best for quick, local operations

Perfect for LINQ

var people = new List<Person> { /* ... */ };

var summary = people
    .Select(p => new
    {
        p.Name,
        IsAdult = p.Age >= 18
    });

foreach (var item in summary)
{
    Console.WriteLine(quot;{item.Name}: {item.IsAdult}");
}

Anonymous Types in Pattern Matching

var data = new { Type = "fruit", Name = "apple" };

// Check properties
if (data is { Type: "fruit" })
{
    Console.WriteLine(quot;Found fruit: {data.Name}");
}

🎯 Quick Recap

Pattern Type What It Does Example
Type Checks what type is string
Declaration Checks type + creates variable is int n
Property Peeks at properties is { Age: 25 }
Positional Matches by position is (0, 0)
List Matches array content is [1, 2, 3]
Relational Compares values >= 10

🚀 Why This Matters

Pattern matching makes your code:

  • Cleaner - Less boilerplate
  • Safer - Compiler catches mistakes
  • Readable - Shows intent clearly
  • Fun - Like solving puzzles!

🌈 The Magic Combo

Combine everything:

string Analyze(object obj) => obj switch
{
    null => "Nothing!",

    int n when n < 0 => "Negative number",
    int n => quot;Number: {n}",

    string { Length: 0 } => "Empty text",
    string { Length: > 100 } => "Long text",
    string s => quot;Text: {s}",

    int[] { Length: 0 } => "Empty array",
    int[] [var first, .., var last]
        => quot;From {first} to {last}",

    Person { Age: >= 18 } p => quot;Adult: {p.Name}",
    Person p => quot;Minor: {p.Name}",

    _ => "Unknown type"
};

🎉 You did it! Pattern matching is now your superpower. Use it to write cleaner, smarter, more expressive code!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.