0Pricing
C# Academy · Lesson

Relational and Logical Patterns

Combine conditions in patterns.

Relational and Logical Patterns is a free C# Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Relational Patterns

A relational pattern compares the input against a constant using <, >, <=, or >=. It matches when the comparison is true.

Introduced in C# 9, relational patterns make range checks concise in switch arms and is expressions without writing explicit comparisons.

int temp = 18;
string level = temp switch
{
    < 0  => "freezing",
    < 15 => "cold",
    < 25 => "mild",
    _    => "hot"
};
System.Console.WriteLine(level);

Relational with is

Relational patterns also work in is expressions, giving readable boolean tests.

n is > 0 reads almost like English and returns a bool you can use in conditions, assignments, or LINQ predicates.

using System;

class Program {
    static void Main() {
        int score = 82;
        bool passed = score is >= 60;
        Console.WriteLine(passed);
    }
}

The and Pattern

The and logical pattern requires both sub-patterns to match. It is perfect for bounded ranges.

>= 1 and <= 12 matches values inside an inclusive range. Without and, expressing two-sided bounds in a single pattern would be impossible.

int month = 6;
bool valid = month is >= 1 and <= 12;
System.Console.WriteLine(valid);

The or Pattern

The or logical pattern matches when either sub-pattern matches. It groups alternative values into one arm.

Instead of repeating arms for related cases, 'a' or 'e' or 'i' collapses them. This keeps switch expressions compact and intention-revealing.

char c = 'e';
string kind = c switch
{
    'a' or 'e' or 'i' or 'o' or 'u' => "vowel",
    _ => "consonant"
};
System.Console.WriteLine(kind);

The not Pattern

The not logical pattern matches when its sub-pattern does not match. The most common use is not null.

It also negates other patterns, such as not 0 or not (> 100), letting you express exclusions clearly inside a single arm.

object? value = "hi";
if (value is not null)
    System.Console.WriteLine("present");

Combining Logical Patterns

Logical patterns compose. You can chain and, or, and not to build rich conditions, using parentheses to control precedence.

Precedence is: not binds tightest, then and, then or. Add parentheses whenever the intent might be ambiguous.

using System;

class Program {
    static string Classify(int n) => n switch {
        < 0 or > 100 => "out of range",
        >= 0 and <= 50 => "low half",
        _ => "high half"
    };
    static void Main() => Console.WriteLine(Classify(75));
}

Ranges in Grading

Relational and logical patterns together model classic grading tables cleanly.

Because arms are checked top to bottom, you can use simple upper bounds, or combine bounds with and for explicit ranges. Both styles are valid; choose the clearer one.

using System;

class Program {
    static char Grade(int s) => s switch {
        >= 90 => 'A',
        >= 80 and < 90 => 'B',
        >= 70 and < 80 => 'C',
        _ => 'F'
    };
    static void Main() => Console.WriteLine(Grade(85));
}

not null with Property Patterns

Combining not null with type and property patterns produces safe, expressive guards.

obj is Person { Name: not null } p matches a non-null Person whose Name is also not null and binds it. This avoids cascading null checks.

record Person(string? Name);

object obj = new Person("Kai");
if (obj is Person { Name: not null } p)
    System.Console.WriteLine(p.Name);

Negating Ranges

You can negate a relational group with not and parentheses to express exclusions.

not (>= 1 and <= 5) matches anything outside the 1 to 5 range. This reads more directly than the equivalent < 1 or > 5 for some readers.

using System;

class Program {
    static void Main() {
        int n = 9;
        bool outside = n is not (>= 1 and <= 5);
        Console.WriteLine(outside);
    }
}

Mixing with Type Patterns

Logical patterns can join type patterns too. o is int or long matches integral numeric types in one check.

This is handy for treating several related types uniformly. Note both sides of or must be compatible with how the result is used.

object o = 5L;
string kind = o switch
{
    int or long => "integral",
    float or double => "floating",
    _ => "other"
};
System.Console.WriteLine(kind);

Readability Guidelines

Logical patterns are expressive but can become dense. Keep arms short, prefer ranges with and, and parenthesize mixed and/or for clarity.

When a condition needs many clauses or external variables, a when guard may read better than a long logical pattern. Choose whichever communicates intent.

int n = 42;
string r = n switch
{
    > 0 and < 10 when n % 2 == 0 => "small even",
    _ => "other"
};
System.Console.WriteLine(r);

Quick Check

Test your understanding of relational and logical patterns.

Recap

Relational patterns (< > <= >=) compare against constants. Logical patterns combine sub-patterns with and, or, and not.

Precedence is not, then and, then or; parenthesize when mixing. Next we cover list and tuple patterns.

Frequently asked questions

Is the “Relational and Logical Patterns” lesson free?

Yes — the full text of “Relational and Logical Patterns” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Relational and Logical Patterns”?

Combine conditions in patterns. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Relational and Logical Patterns” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. switch Expressions
  2. Type and Property Patterns
  3. Relational and Logical Patterns
  4. List and Tuple Patterns
← Back to C# Academy