C# tutorials > Modern C# Features > C# 6.0 and Later > How does pattern matching work on `Span<char>` or `ReadOnlySpan<char>`?
How does pattern matching work on `Span<char>` or `ReadOnlySpan<char>`?
Understanding Pattern Matching with Span<char> and ReadOnlySpan<char> in C#
C# offers powerful pattern matching capabilities. Applying these to Span<char>
and ReadOnlySpan<char>
allows for efficient and expressive code when dealing with character sequences. This tutorial will explain how to effectively use pattern matching with these types.
Introduction to Pattern Matching with Spans
Span<char>
and ReadOnlySpan<char>
provide a contiguous view into a block of memory, avoiding unnecessary allocations and copying. Pattern matching enables you to check the content and structure of these spans directly without resorting to string conversions or manual indexing. While you can't directly use `is` with string literals against a `Span
Example: Checking Span Length
This example uses a switch expression to check if the span is empty or shorter than 5 characters. This demonstrates a simple application of pattern matching based on the length of the span.
public static bool IsEmpty(ReadOnlySpan<char> span)
{
return span.Length switch
{
0 => true,
_ => false
};
}
public static bool IsShort(ReadOnlySpan<char> span)
{
return span.Length switch
{
< 5 => true,
_ => false
};
}
Example: Matching Specific Characters
Here we use positional pattern matching along with the discard pattern (..
) to check if a span starts with specific characters. This approach allows efficient prefix matching without explicit substring operations.
public static string StartsWithPrefix(ReadOnlySpan<char> span)
{
return span switch
{
['H', 'e', 'l', 'l', 'o', ..] => "Starts with Hello",
['W', 'o', 'r', 'l', 'd', ..] => "Starts with World",
_ => "Doesn't match any known prefix"
};
}
Example: Using Slice with Pattern Matching
This example shows how to use pattern matching on individual characters within a ReadOnlySpan<char>
. It first checks if the span has at least three characters, and then uses pattern matching to check the value of the third character.
public static string CheckThirdCharacter(ReadOnlySpan<char> span)
{
if (span.Length >= 3)
{
return span[2] switch
{
'A' => "Third character is A",
'B' => "Third character is B",
_ => "Third character is neither A nor B"
};
}
else
{
return "Span is too short";
}
}
Real-Life Use Case: Parsing Configuration Files
Imagine parsing a configuration file where you need to extract values based on specific prefixes. Using Span<char>
with pattern matching can efficiently identify and process different configuration settings without unnecessary string allocations. For example, you might check if a line starts with 'Server:', 'Port:', or 'Timeout:' using positional pattern matching.
Best Practices
Span<char>
to avoid converting sections of the span to strings when you only need to inspect specific parts.
When to Use Pattern Matching with Spans
Use pattern matching with Span<char>
and ReadOnlySpan<char>
when you need to efficiently inspect the contents of a character sequence without unnecessary allocations. This is particularly useful in performance-critical scenarios like parsing, data processing, and text manipulation.
Memory Footprint
Using Span<char>
and ReadOnlySpan<char>
reduces memory allocation because they provide a view into existing memory without creating copies of strings or character arrays. When coupled with pattern matching, you avoid intermediate string operations, further minimizing memory usage.
Alternatives
Alternatives to pattern matching on spans include:
Pros
Cons
FAQ
-
Can I use regular expressions with `Span<char>` directly?
No, the standard regular expression classes in .NET primarily work with strings. You would need to convert the `Span<char>` to a string to use them, which can negate some of the performance benefits of using spans in the first place. -
Is pattern matching on `Span<char>` case-sensitive?
Yes, pattern matching is case-sensitive by default. To perform case-insensitive matching, you can convert the span to lowercase or uppercase, or use custom logic within your patterns. -
What happens if the span is null?
A `Span<char>` or `ReadOnlySpan<char>` cannot be null. However, it can be empty (Length == 0). You should handle the empty span case in your pattern matching logic.