Follow

Follow
C# 11 List Patterns

C# 11 List Patterns

The shape of a Sequence!

Joshua Steward's photo
Joshua Steward
ยทDec 1, 2022ยท

4 min read

C# and Pattern Matching

With each latest iteration of C#, we see more and more pattern matching. Frankly, I'm deeply excited to see this evolution. C# of course can still be considered an Object Oriented language but MS has taken the Multi-modal moniker and then ran with it.

F# has been an incredible source of inspiration for the C# team, not to mention the Pythion influence when we left Program in the background. So long old friend ๐Ÿ‘‹ We've seen a great deal of Functionally oriented features. From first-class tuples, immutable types, and of course pattern matching!

Pattern Power ๐Ÿ’ช

What is a Pattern again?

Simply put, a pattern is the shape of an input that you expect to see. You declare what to expect and allow our friend Roslyn to create the ultimate boolean expression to fulfill the pattern search.

List Patterns

The latest addition to the crowd is List Patterning We can take any sequence and describe what we'd like to switch on from a mix of syntax cues.

Patterns are described by

  • Square brackets []

Within the brackets, we can match

  • Any single element _ with the Discard Pattern

  • Many contiguous elements .. with the Slice Pattern

We can even mix in existing patterns to further refine our Sequence Pattern

  • Relational Patterns < , >= , etc.

  • Logical Patterns and, or , not

And don't forget! Even with these complex List Patterns we still have a bit of a safety net to enforce fully closed pattern expressions as usual with switch {}


To Action - The basics

We have a basic Discard match

[Fact]
public void Match_Discard_Pattern()
{
    var seq = new[] { 1, 2 };
    var result = seq switch
    {
        [_, 2] => true,
        _ => false
    };
    result.Should().BeTrue();
}

Next, we'll Slice the sequence

[Fact]
public void Match_Slice_Pattern()
{
    var seq = new[] { 1, 2 };
    var result = seq switch
    {
        [..] => true,
        _ => false
    };
    result.Should().BeTrue();
}

We can use Relational Patterns

[Fact]
public void Match_Relational_Pattern()
{
    var seq = new[] { 1, 2 };
    var result = seq switch
    {
        [_, > 1] => true,
        _ => false
    };
    result.Should().BeTrue();
}

We can even mix in Logical Patterns

[Fact]
public void Match_Relational_Logical_Pattern()
{
    var seq = new[] { 1, 2 };
    var result = seq switch
    {
        [_, > 1 and < 3] => true,
        _ => false
    };
    result.Should().BeTrue();
}

Level Up Your Patterns

List Patterns are recursive and can contain any combination of nested Patterns. Combining all the available patterns, we can thoroughly inspect the content of a sequence and enforce positional relationships within the sequence. If we have a set of objects, say Person

public sealed record Person(string Name, int Age);

For us to express the idea that Josh must be second in our sequence we can write the following pattern

[Fact]
public void Match_Positional_Pattern()
{
    var seq = new Person[]
    {
    new("Mike", 23),
    new("Josh", 67)
    };
    var result = seq switch
    {
        [_, ("Josh", _)] => true,
        _ => false
    };
    result.Should().BeTrue();
}

We can even express a Property Pattern

[Fact]
public void Match_Property_Pattern()
{
    var seq = new Person[]
    {
    new("Mike", 23),
    new("Josh", 67)
    };
    var result = seq switch
    {
        [_, { Age: > 18 }] => true,
        _ => false
    };
    result.Should().BeTrue();
}

And don't forget we can capture sequence elements in our switch expression

[Fact]
public void Match_Var_Pattern()
{
    var seq = new Person[]
    {
    new("Mike", 23),
    new("Josh", 67)
    };
    var result = seq switch
    {
        [_, var person] => person,
        _ => null
    };
    result.Should().BeEquivalentTo(seq[1]);
}

Imagination is the limit!

Don't stop here! These new powerful patterns are just aching to be leveraged in new and brilliant ways. The C# team keeps delivering powerful advancements to an already incredible language.

Please share your creativity in the comments, what can you do with these patterns!?

ย 
Share this