Daily Knowledge Drop
Pattern matching
can use the is
, not
, and
and or
keywords individually in a statement, but also use the keywords together to form an enhanced, more complex statement.
Individual
is keyword
Common usages of the is
keyword is for null checks
and type tests
:
A null check
being performed:
int? age = 12;
// check if the value of age
// is a valid number (i.e. not null)
if (age is int number)
{
Console.WriteLine($"'age' has the value of:{number}");
}
else
{
Console.WriteLine("'age' has no value");
}
A type check
being performed (for performance improvements in this example):
public int SumListChecked(IEnumerable<int> enumerable)
{
var runningSum = 0;
// Check the type
if (enumerable is List<int> list)
{
foreach (var item in list)
{
runningSum += item;
}
return runningSum;
}
// all others
foreach (var item in enumerable)
{
runningSum += item;
}
return runningSum;
}
not keyword
The not
keyword can be used in conjunction with the is
keyword to perform a null check
:
string? outputMessage = "This message should be output!";
// explicitly check that the string is not null
if (outputMessage is not null)
{
Console.WriteLine(outputMessage);
}
and, or keywords
The and
and or
keywords are commonly used in a switch expression
for pattern matching
:
string GetGrade(int percentage) =>
percentage switch
{
(< 0) or (> 100) => "Invalid",
(>= 0) and (< 40) => "Fail",
(>= 40) and (< 70) => "Average",
(>= 70) => "Excellent",
};
Enhanced matching
All the keywords can be used together for a more complex pattern matching expression - in this example to validate an email address
(there are definitely better, more comprehensive ways to validate an email address than using pattern matching, and although the below is not a complete and entirely valid way to validate an email address, it is sufficient for this demo)
The first step is to loop through each character in the email address to determine if its valid for an email address:
bool IsValidEmailAddress(string email)
{
foreach (var c in email)
{
var result = IsValidChar(c);
if (!result)
{
return false;
}
}
return true;
}
If any of the characters are invalid according to the IsValidChar
method, then the email string as a whole is invalid.
The IsValidChar
is where the enhanced, more complex pattern matching takes place. The method is an expression-bodied method
which in turn used pattern matching
:
bool IsValidChar(char c) =>
c is ((>= 'A' and <= 'Z') // capital letters
or (>= 'a' and <= 'z') // lower case
or (>= '0' and <= '9') // numbers
or '@' // allowed symbols
or '.'
or '-'
or '+'
and not ' ');
Executing the above code with the following example:
var emailToValidate = "learn@alwaysdeveloping.com";
Console.WriteLine($"'{emailToValidate}' a valid email " +
$"address?: {IsValidEmailAddress(emailToValidate)}");
var anotherEmailToValidate = "invalid123, invalid";
Console.WriteLine($"'{anotherEmailToValidate}' a valid email " +
$"address?: {IsValidEmailAddress(anotherEmailToValidate)}");
The output:
'learn@alwaysdeveloping.com' a valid email address?: True
'invalid123, invalid' a valid email address?: False
Notes
As Pattern matching
is a fairly new addition to C#, I have not seen it extensively used, and have no extensively used it myself. However the more I learn about the usages of it, the more it gets incorporated into my coding daily.
In this demo pattern matching
is certainly more readable and easier to understand than some other methods (regex for example) - but what one gains in maintainability and readability, one might lose in performance. However, the important thing to know is there are options, and being better informed about each option allows for the best technique to be chosen for each use case.
References
Daily Drop 138: 15-08-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.