๐ŸŽ“ A1Learner
๐Ÿ”
0 of 28 lessons completed

C# Patterns at Depth

Relational patterns compare a value with a constant inside a pattern. Combinators join simple patterns into one test with and, or, and not.

Relational arms in a switch

Each arm compares the score with one boundary. A score of 85 lands in the B band.

using System;

class Program
{
    static string Grade(int score)
    {
        return score switch
        {
            >= 90 => "A",
            >= 80 => "B",
            >= 70 => "C",
            _ => "F",
        };
    }

    static void Main(string[] args)
    {
        Console.WriteLine(Grade(85));
    }
}

Combining patterns with and and or

The grade arm needs both comparisons to hold. The temperature arm fires when either extreme matches.

using System;

class Program
{
    static string Grade(int score)
    {
        return score switch
        {
            >= 80 and < 90 => "B",
            >= 90 => "A",
            _ => "Other",
        };
    }

    static string Describe(int temp)
    {
        return temp switch
        {
            < 0 or > 35 => "Extreme",
            _ => "Mild",
        };
    }

    static void Main(string[] args)
    {
        Console.WriteLine(Grade(85));
        Console.WriteLine(Describe(40));
    }
}

The not pattern and char ranges

The is not null test guards the length read. One combined pattern checks that a char sits in the lowercase range.

using System;

class Program
{
    static void Main(string[] args)
    {
        string word = "hello";
        if (word is not null)
        {
            Console.WriteLine(word.Length);
        }
        char c = 'q';
        Console.WriteLine(c is >= 'a' and <= 'z');
    }
}

Example

using System;

class Program
{
    static string Category(int age)
    {
        return age switch
        {
            not (>= 0 and <= 120) => "Unknown",
            >= 0 and < 13 => "Child",
            >= 13 and < 20 => "Teen",
            _ => "Adult",
        };
    }

    static void Main(string[] args)
    {
        Console.WriteLine(Category(15));
        Console.WriteLine(Category(200));
    }
}

Key points

  • A relational pattern uses a comparison such as >= 80 inside an arm.
  • The and combinator matches only when both sides match.
  • The or combinator matches when either side matches.
  • The not combinator matches when the inner pattern fails.
  • The pattern is not null matches every value except null.
  • Char values support relational patterns, so a range of letters is one test.
  • Arms still run from top to bottom, and the first match wins.

In this example, the Category method switches over an age. The first arm negates a whole range, so an age of 200 matches it and prints Unknown. An age of 15 passes the range check and matches the teen arm.

Note

Parentheses group a combined pattern when not negates the whole group.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Which pattern matches a score of 85 but not a score of 95?