# Switch Expressions and Pattern Matching — C#/.NET

Source: https://www.skillbyai.com/en/dotnet/c-patterns

> Use type, property, relational and list patterns with switch expressions.

## Asking questions about the shape of data

**Pattern matching** tests a value against a shape and can extract parts of it in one step. The `is` operator with a **type pattern** checks and casts: `if (shape is Circle c)`. **Switch expressions** (`value switch { pattern => result, ... }`) return a value and must be **exhaustive**; `_` is the discard pattern that matches anything. Patterns combine: **property patterns** (`{ Country: "IN", Total: > 1000 }`), **relational patterns** (`< 0`, `>= 18`), **logical patterns** (`and`, `or`, `not`), **positional patterns** for deconstructable types such as records and tuples, and **list patterns** (`[first, .., last]`). `is not null` is the idiomatic null check. Pattern matching often replaces long `if/else` chains and type-checking casts, and the compiler warns when a switch expression misses a case.

## Shipping cost with patterns

Each arm is checked in order; the first matching arm wins.

```cs
decimal ShippingCost(Order order) => order switch
{
    { Total: >= 1000m }                     => 0m,      // free shipping
    { Country: "IN", Express: true }      => 99m,
    { Country: "IN" }                      => 49m,
    { Country: "US" or "CA" }             => 15m * order.Items.Count,
    _                                       => 25m,
};

string Describe(int[] values) => values switch
{
    []               => "empty",
    [var only]       => $"one item: {only}",
    [var first, .., var last] => $"from {first} to {last}",
};

record Order(string Country, decimal Total, bool Express, List<string> Items);
```

## Order arms from specific to general

Because the first match wins, put the most specific patterns first. The compiler reports an error if an arm can never be reached because an earlier arm already covers it.

**Quiz:** What does `_` mean in a switch expression?

- [x] The discard pattern that matches any value not matched earlier
- [ ] A syntax error
- [ ] A null check
- [ ] The default value of the type

*Answer:* The discard pattern that matches any value not matched earlier. The discard pattern catches everything that earlier arms did not match.
