Skip to main content
A positional pattern is a pattern matching construct in C# that deconstructs an expression into its constituent parts and applies nested patterns to those resulting values based on their ordinal position. It relies on the presence of a compatible Deconstruct method or inherent tuple semantics to extract values for evaluation.

Syntax

The pattern is defined by enclosing a comma-separated list of nested patterns within parentheses. A type declaration can optionally precede the parentheses to enforce a type check prior to deconstruction.

Mechanics of Deconstruction

For a positional pattern to evaluate a custom type, the type must implement a Deconstruct method (either as an instance method or an extension method). The method must return void and declare out parameters corresponding to the values being extracted. A type can overload the Deconstruct method with different numbers of out parameters. During pattern matching, the compiler automatically resolves the positional pattern to the specific Deconstruct overload that matches the exact number of provided nested patterns.
When the pattern is evaluated, the compiler invokes the matched Deconstruct method, binds the out parameters to temporary variables, and applies the nested patterns to those variables in the exact order they are declared.

Positional Records

In modern C#, positional record types are the primary and most idiomatic targets for positional patterns. When a positional record is defined, the compiler automatically generates a Deconstruct method behind the scenes that corresponds to the primary constructor parameters.

Pattern Application

Positional patterns support nesting any other valid C# pattern (e.g., constant, relational, property, or discard patterns) at each ordinal position.
During the evaluation of the code above:
  1. The compiler checks if obj is of type Point.
  2. If true, it invokes Point.Deconstruct(out int x, out int y).
  3. It applies the constant pattern 5 to the first positional value (x).
  4. It applies the relational pattern >= 10 to the second positional value (y).

Variable Declaration

Positional patterns can declare new variables to capture the deconstructed values. This is achieved using the declaration pattern within the positional slots.

Omitting the Type Declaration

The explicit type declaration preceding the parentheses can be omitted for any type (including custom classes, records, and tuples) as long as the static type of the expression being evaluated is already known at compile time and provides a compatible Deconstruct method.

Discards

If a specific ordinal position is irrelevant to the match, the discard pattern (_) can be used to ignore that specific out parameter during deconstruction. This prevents unnecessary variable allocation and clarifies intent.
Tired of Poor C# Skills? Fix That With Deep Grasping!Learn More