How it works
A switch expression chooses a value from a set of ordered patterns. Unlike a switch statement, it belongs inside an expression and produces a result. It works well when a decision table maps a small input domain to a label, price band, or next action. Relational patterns describe ranges without scattering the same input across several comparisons.
Read each arm as a rule, and put more specific rules before broad fallbacks. The discard pattern supplies a final answer for values that have not matched earlier arms. Exhaustiveness matters because real inputs often include values outside the examples in a requirement. A default label should represent an intentional policy, rather than hiding invalid values under a successful category.
Walk through the example. The Label function rejects negative scores first, then assigns low, medium, and high labels using upper boundaries. The inputs zero, nine, ten, nineteen, and twenty show exactly where one rule stops and the next begins. Each call returns one string, so output formatting stays separate from the classification decision.
Watch the boundary. An upper-bound-only rule can accidentally accept invalid negative values unless an earlier arm handles them. Reordering the negative check below a broad less-than-ten arm changes behavior. Check boundary values on both sides of every transition. If an invalid value should stop processing, throw or return a failure result rather than choosing a normal category.
Practice independently. Model shipping sizes with an explicit invalid category, a letter band, a parcel band, and a heavy band. Write the table of boundary inputs before writing code. Implement the classification as a function and print a compact report from a loop. Add one new band and show which previous boundary tests need to change and which must remain unchanged.
A working example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
string Label(int score) => score switch
{
< 0 => "invalid",
< 10 => "low",
< 20 => "medium",
_ => "high"
};
foreach (int score in new[] { -1, 0, 9, 10, 19, 20 })
Console.WriteLine($"{score}:{Label(score)}");
Expected output
-1:invalid 0:low 9:low 10:medium 19:medium 20:high
Order invalid and narrow cases before broad ranges.