C# 7 Pattern Matching and Tuples Guide
C# 7 introduced significant enhancements to modern software development, most notably first-class support for tuples and foundational pattern matching features. These additions streamlined common programming tasks by simplifying how developers return multiple values from methods, inspect types, and branch logic conditionally. This article outlines the specific features introduced for both tuples and pattern matching in C# 7, detailing their syntax, capabilities, and practical benefits.
Tuples in C# 7
Prior to C# 7, returning multiple values required using
out parameters, custom classes/structs, or the
allocate-heavy System.Tuple. C# 7 introduced built-in
language support for tuples backed by the lightweight
System.ValueTuple value type.
ValueTuple and Tuple Syntax
Tuples in C# 7 are value types, which avoids heap allocation and improves performance. Developers can create and return tuples using concise, parenthesis-based syntax:
(double Latitude, double Longitude) GetCoordinates()
{
return (37.7749, -122.4194);
}
var coords = GetCoordinates();
Console.WriteLine($"Lat: {coords.Latitude}, Long: {coords.Longitude}");Tuple Deconstruction
C# 7 allows consumers to unpack the elements of a tuple directly into individual variables:
var (lat, lon) = GetCoordinates();Developers can also define a Deconstruct method within
any class or struct to enable tuple-like deconstruction syntax on custom
types:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public void Deconstruct(out string first, out string last)
{
first = FirstName;
last = LastName;
}
}
// Usage:
var person = new Person { FirstName = "Jane", LastName = "Doe" };
var (first, last) = person;Pattern Matching in C# 7
C# 7 introduced the first stage of pattern matching, allowing developers to test the shape and type of data cleanly without verbose casting.
Type Patterns with the
is Expression
The is expression was enhanced to test an expression's
type and assign it to a new local variable simultaneously, removing the
need for separate as casting and null checking:
if (input is string text)
{
Console.WriteLine($"String length: {text.Length}");
}If input is a string, text is
scoped to the if block, strongly typed, and safe to
use.
Pattern Matching in
switch Statements
The switch statement was expanded to support pattern
matching across any data type, rather than being restricted to
primitives and strings:
- Type Patterns: Cases can match specific types and declare variables.
- The
whenClause: Cases can include boolean conditions (guards) to filter matches further. - Order-Dependent Evaluation: Unlike traditional
switches, pattern-based
caselabels are evaluated sequentially, requiring more specific patterns to appear before broader ones.
switch (shape)
{
case Circle c when c.Radius > 10:
Console.WriteLine($"Large circle with radius {c.Radius}");
break;
case Circle c:
Console.WriteLine($"Small circle with radius {c.Radius}");
break;
case Rectangle r:
Console.WriteLine($"Rectangle with area {r.Width * r.Height}");
break;
case null:
Console.WriteLine("Shape is null");
break;
default:
Console.WriteLine("Unknown shape");
break;
}The var Pattern
C# 7 also introduced the var pattern, which matches any
value (including null) and assigns it to a newly declared
variable. This pattern is commonly used within when clauses
to temporarily capture intermediate results.