C# Deconstruction Patterns
A deconstruction pattern tests the parts that a value deconstructs into. It can also test properties nested inside other properties in the same match.
Positional patterns on a record
The Point record deconstructs into X and then Y. The second test captures the second part in a variable.
using System;
class Program
{
static void Main(string[] args)
{
Point point = new Point(0, 0);
Console.WriteLine(point is (0, 0));
if (point is (0, var y))
{
Console.WriteLine(y);
}
}
}
record Point(int X, int Y);A switch over a tuple
Each arm holds a pattern for both elements of the tuple. The first arm needs a true first element and a score of at least 80.
using System;
class Program
{
static string Result(bool present, int score)
{
return (present, score) switch
{
(true, >= 80) => "Pass",
(true, _) => "Try again",
_ => "Absent"
};
}
static void Main(string[] args)
{
Console.WriteLine(Result(true, 85));
}
}Nested property patterns
The outer pattern tests the Reading property of the sensor. The inner pattern tests the Value inside that reading.
using System;
class Program
{
static void Main(string[] args)
{
Sensor sensor = new Sensor();
sensor.Reading = new Reading();
sensor.Reading.Value = 150;
if (sensor is { Reading: { Value: > 100 } })
{
Console.WriteLine("High");
}
else
{
Console.WriteLine("Low");
}
}
}
class Sensor
{
public Reading Reading { get; set; }
}
class Reading
{
public int Value { get; set; }
}Example
using System;
class Program
{
static void Main(string[] args)
{
Order order = new Order("Pen", 12) { Priority = true };
string label = order switch
{
("Pen", >= 10) { Priority: true } => "Bulk priority",
("Pen", _) { Priority: true } => "Priority",
_ => "Standard"
};
Console.WriteLine(label);
}
}
record Order(string Item, int Count)
{
public bool Priority { get; init; }
}Key points
- A record deconstructs into its constructor parameters in order.
- A positional pattern lists the expected parts inside parentheses.
- A variable inside the pattern captures that part for later use.
- A tuple can be matched as a whole, with a pattern for each element.
- A property pattern can nest, so one test reaches through an object graph.
- A nested test fails as a whole when any part fails to match.
In this example, an Order record holds an item name and a count. The matching arm uses a positional pattern for both parts. The same arm also tests the Priority property. The bulk priority label prints.
Note
A type needs a Deconstruct method or a record shape before a positional pattern can split it.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does the pattern in `new Point(0, 0) is (0, 0)` test?