Skip to content

C# Positional Pattern — Complete Guide

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about C# Positional Pattern. We cover key concepts, practical examples, and best practices.

You have a tuple or an object with a Deconstruct method and you want to match its components in a switch expression. You write nested conditions to extract and compare each part individually. Positional patterns let you match on the decomposed shape directly.

Wrong

var point = (3, 4);
if (point.Item1 == 0 && point.Item2 == 0) Console.WriteLine("Origin");
else if (point.Item1 > 0 && point.Item2 == 0) Console.WriteLine("On X axis");

Output: Works but verbose. Does not scale with more complex shapes.

var point = (3, 4);
var description = point switch
{
    (0, 0) => "Origin",
    ( > 0, 0) => "On positive X axis",
    (0, > 0) => "On positive Y axis",
    var (x, y) => $"At ({x}, {y})"
};
Console.WriteLine(description);

Output: "At (3, 4)".

The positional pattern (0, 0) matches a tuple or object at position 0,0. For custom types, implement Deconstruct:

public record struct Point(int X, int Y);
// Deconstruct is automatic for records
Point p = new(3, 4);
var result = p switch { (0, 0) => "Origin", _ => "Other" };

Prevention

  • Use positional patterns with tuples for quick multi-value matching.
  • Implement Deconstruct on your types to enable positional matching.
  • Use records — they auto-generate Deconstruct.
  • Combine with when clauses for additional conditions.
  • Use var patterns to capture and name the deconstructed values.
  • Nest positional patterns: ( > 0, ( "admin" or "user" )).

Common Mistakes with positional pattern

  1. Forgetting deriving (Show, Eq) on custom data types needed for debugging
  2. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  3. Using head and tail instead of pattern matching, causing runtime errors on empty lists

These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

What types support positional patterns?

Any type with a Deconstruct method (either as a member or as an extension method). Tuples, records, and KeyValuePair<TKey, TValue> all support positional patterns out of the box.

Can I nest positional patterns?

Yes. ( > 0, ( "admin", _ )) matches a tuple whose second element is itself a tuple with first element "admin". Nesting positional patterns works to arbitrary depth.

What is the difference between positional and property patterns?

Positional patterns match on the position within a Deconstruct call. Property patterns match on named properties: { X: 0, Y: 0 }. Use positional patterns for tuples and small types; use property patterns for larger objects with meaningful member names.

Positional patterns are used in DodaZIP to match archive entry headers by their byte positions. For more C# patterns, visit DodaTech.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro