C# / CHAPTER 06

Pattern matching and exhaustive decisions

Intermediate

Use patterns to connect input shape with permitted operations.

By the end of this chapter

  • Narrow nullable values
  • Order switch arms correctly
  • Handle unmatched inputs deliberately

The idea

Pattern matching combines a test with access to the value it establishes. A declaration pattern such as value is string text succeeds only for a non-null string and supplies a usable local variable. Relational patterns describe ranges without converting unrelated runtime types. The examples use modern C# syntax supported by C# 9 or later.

A switch expression chooses the first matching arm, so broad patterns can hide more specific cases. Describe boundary values explicitly and provide a deliberate fallback when the input domain is not closed. An exhaustive-looking list of examples is not proof that all runtime values have been covered. For domain decisions, test exact thresholds as well as the intervals between them.

C# example
using System;
static string Band(int score) => score switch {
  < 0 or > 100 => "invalid",
  >= 80 => "high",
  >= 50 => "middle",
  _ => "low"
};
Console.WriteLine($"{Band(80)} {Band(101)} {Band(49)}");
Result
high invalid low

Invalid values are rejected before the broad high-score arm, and equality belongs to the stated lower threshold.

Try it yourself

Classify an object as a nonempty string, a nonnegative int, or unsupported, preserving zero as valid.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Which input satisfies value is string text?