C# Pattern matching

Overview of scenarios where you can use pattern matching. These techniques can improve the readability and correctness of your code.

Reduce nested if-else

We have the following class

IAnimal animal = new Cat("Fred", 12);

then with a single if we can determine if the animal is more than 10 years old and has the name of fred

if(animal is Cat { CatYears: >10, Name: "Fred"} myCat)
{
	Console.WriteLine($"{myCat.CatYears} old");
}

Null checks

One of the most common scenarios.

string? message = MaybeString();
if(message is not null) 
{
	Console.WriteLine(message);
}

Compare discrete values

You can test a varaible to find a match on specific values

public State PerformOperation(string command) =>
	command switch
	{
		"SystemTest" => RunDiagnostics(),
		"Start" => StartSystem(),
		"Stop" => StopSystem(),
		_ => throw new ArgumentException("Invalid string value", nameof(command)),
	};

_ is the discard pattern that matches all values. It handles any error conditions where the value doesn’t match one of the defined values.

Relational patterns

You can use relational patterns to test how a value compares to contants.

string WaterState(int tempInFahrenheit) =>
	tempInFahrenheit switch
	{
		(>32) and (<212) => "liquid",
		<= 32 => "solid",
		>= 212 => "gas"
	};

Multiple inputs

You can write patterns that examine multiple properties of an object.

consider the following Order record

public record Order(int Items, decimal Cost);

this examines the number of items and the value of an order to calculate a discount

public decimal CalculateDiscount(Order order) =>
	order switch
	{
		{ Items: >10, Cost: >1000.00m } => 0.10m,
		{ Items: >5, Cost: > 500.00m } => 0.05m,
		{ Cost: >250.00m } => 0.02m,
		null => throw new ArgumentNullException(nameof(order), "can't calculate on null"),
		var someObject => 0m,
	};

Reference(s)

https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching
https://ianvink.wordpress.com/2021/12/11/part-1-c-10-pattern-matching-or-the-death-of-if-else/