Introduction to Pattern Matching in C#

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

C# Programming Guide

Functional programming is a great way to write code that is often clearer and easier to maintain than imperative code. Pattern matching is a feature of some functional programming languages that allows programmers to perform complex data processing.

This .NET programming tutorial shows how you can apply functional programming techniques to C#. It walks through the basics of pattern matching in C# and shows how it applies to the popular programming language.

Looking to learn C# in a class or online course environment? We have a list of some of the Top Online Courses to Learn C# Programming.

What is Pattern Matching in C#?

Pattern matching is a powerful tool in C# that allows you to match against data structures and objects of various types. The most common way to do this is by using finite automata and regular expressions, but there are other methods as well.

Initially introduced in C# 7, pattern matching can be used to extract values from an expression elegantly. C# 8 improved pattern matching further by introducing several new pattern types. C# 9 improved it further by introducing new relational and logical patterns.

Developers define a pattern and then check that it matches an input value. It is the process of analyzing an input string, extracting patterns from it, and then looking for a specific pattern to match. This can be done by using regular expressions or using more complicated algorithms such finite-state automata and context-free grammars.

The outcome of pattern matching is either success or failure; i.e., either the pattern will match, or it will not match.

Pattern matching defines a pattern that matches against some input and then executes some code based on whether the pattern matched. This can be useful for deciding what to do with a user request or even in simple tasks like checking whether an integer is negative or positive. It can also be a handy tool for writing more concise code.

Why Developers Use Pattern Matching?

Developers can use pattern matching to write more simple, efficient, readable, and maintainable code. Because pattern matching makes traversing complicated object structures simpler, you will find integrating it in your application’s code beneficial, especially when using constructs such as if-else and switch-case.

Pattern Matching has many uses, ranging from the simple checking of user input to the implementation of more complex algorithms. Pattern matching is a concept which allows programmers to match the pattern of data they are working with and using that pattern to make decisions.

Read: Top Project Management Tools for C# and .NET Developers

What are the Downsides of Pattern Matching in C#?

There are also some downsides to using pattern matching in C#. For example, when a developer uses pattern matching, they must always specify the exact type of data that they are looking for. This can be a bit difficult to do, particularly if they are trying to match a complex type of data.

Another downside to pattern matching is that it can be a bit slow when compared to other techniques for processing data. This is because pattern matching requires the program to search through each potential match until it finds one that matches the data you are looking for.

How Does Pattern Matching Work in C#?

The following steps show how a typical pattern matching process works in C# software development:

  • The input is matched against the pattern.
  • If the input matches the pattern, then the match succeeds and processing continues.
  • If there are no matches, then no match succeeds and processing continues with another pattern, if one exists, or with default behavior otherwise.

When you want to match a pattern against an input, the input is split into its constituent parts. Each part is then matched against the corresponding part of the pattern. If the characters match, that pattern portion is considered to have successfully matched. If none of the characters match, the entire pattern is considered to have failed.

What is Lexical Analysis?

A simple example of pattern matching is a regular expression. A regular expression is a string that matches a specific sequence of characters, such as “abc”. A string could be matched by this regular expression if it contained the characters “abc” in that order.

The process of matching a string with a regular expression is called lexical analysis, or lexing for short. This process breaks down each character in order to determine whether they match any part of a particular pattern. If they do not, then there is no match; if they do match, then a match has occurred and further processing will continue.

Logical Patterns and Pattern Matching in C#

If you use logical patterns, you may not use the operators and, or, and not. It is important to note that you may utilize logical and relational patterns individually or together. In C#, pattern matching has become more versatile with the advent of conjunctive, disjunctive, and negation patterns.

Both sides of the conjunction must match for the and keyword to work. On the contrary, the or keyword requires any of the patterns to match. The not keyword represents negation and demands that the pattern never satisfies the provided condition.

How to Check for Null Values While Pattern Matching in C#

A common use case for pattern matching is checking for null values. The following code snippet illustrates how this can be accomplished:

int? n = 100;
if (n is int number)
{
    Console.WriteLine($"The value of the nullable int variable n is {number}");
}
else
{
    Console.WriteLine("The nullable int variable n is null or doesn't have a value");
}

Read: Nullable Reference Types in C#

Relational Patterns and Pattern Matching in C#

Relational patterns in C# 9 make use of relational operators such as less than <, less than or equal to <=, greater than >, and greater than or equal to >=. When compared to a constant value, a relational pattern enables you to define that an input value must meet a relational constraint. You can see how to deal with relational patterns in the following C# code example:

public static LogLevel GetLogLevel(int level) => level switch
{
    <= 0 => LogLevel.Information,
    <= 1 => LogLevel.Verbose,
    <= 2 => LogLevel.Error,
    <=3 => LogLevel.Warning,
    _ => LogLevel.Information,
};

Final Thoughts on Pattern Matching in C#

Pattern matching allows programmers to evaluate an expression to see whether it has particular properties. Pattern matching has been available in functional programming languages like Haskell since 1988, but it has only recently become popular in mainstream languages like C# and Scala. This is because it has been challenging to implement pattern matching efficiently until recently.

Read more C# programming tutorials and guides to software development.

Joydip Kanjilal
Joydip Kanjilal
A Microsoft Most Valuable Professional in ASP.NET, Speaker, and Author of several books and articles. More than 25 years of experience in IT with more than 18 years in Microsoft .NET and its related technologies. He was selected as a Community Credit Winner at http://www.community-credit.com several times. He has authored 8 books and more than 500 articles in some of the most reputed sites worldwide including MSDN, Info World, CodeMag, Tech Beacon, Tech Target, Developer, CodeGuru, and more.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read