.NET HELP

C# Pattern Matching Expressions (How It Works For Developers)

Pattern matching in C# is a powerful feature that was introduced in C# 7.0 and has since been expanded upon in subsequent versions. It allows developers to write more concise and expressive code when dealing with conditional statements, type checking, and deconstruction of objects.

Pattern matching expressions provide a flexible and intuitive way to match values against patterns and execute corresponding code blocks. In this article, we will explore the intricacies of pattern matching expressions in C#, including syntax, use cases, and code examples. At the end of the article, we will also explore a bit about IronPDF PDF Generation Library from Iron Software to generate a PDF document on the fly in C# applications.

Benefits of Pattern Matching in C#

Pattern matching in C# code presents a plethora of advantages:

  • Enhanced readability: Pattern matching simplifies complex conditional logic, making your code easier to understand and follow for both yourself and other developers.
  • Reduction in lines of code: By condensing intricate conditional statements into concise patterns, pattern matching helps streamline your codebase, leading to fewer lines of code and a more succinct implementation.
  • Improved maintainability: The clarity offered by pattern matching promotes easier code maintenance and debugging. With patterns clearly delineated, it becomes simpler to identify and modify specific logic blocks as needed without affecting the rest of the codebase.
  • More expressive algorithms: Pattern matching empowers developers to express algorithms in a more natural and intuitive manner. By aligning code structures with problem-solving paradigms, pattern matching facilitates the creation of algorithms that closely resemble their conceptual models.

Types of Pattern Matching in C#

Pattern matching is supported by the following expressions:

  • is expression
  • switch statements
  • switch expressions

The following patterns can be used to match with the constructs:

Declaration and Type Patterns

Declaration and type patterns are essential tools in C# for checking the compatibility of expression run-time types with given types. With declaration patterns, you can both check compatibility and declare a new local variable simultaneously. Consider the following example:

object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: iron software is awesome!
}
object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: iron software is awesome!
}
$vbLabelText   $csharpLabel

Here, the declaration pattern ensures that if the expression greeting matches the type string, it's assigned to the variable message, enabling subsequent operations.

When any of the following conditions hold true, the Declaration Pattern holds good:

  • The run-time type of the expression is T.
  • The run-time type of the expression derives from T, implements interface T, or can be implicitly converted to T.
  • The run-time type of the expression is a nullable value type with the underlying type T.
  • A boxing or unboxing conversion exists from the run-time type of the expression to type T.

Consider the following example demonstrating the above conditions:

int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
    Console.WriteLine(a + b);  // output: 53
}
int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
    Console.WriteLine(a + b);  // output: 53
}
$vbLabelText   $csharpLabel

Here, nullableX matches the pattern because it's a nullable value type with the underlying type int, and boxedy matches because it can be unboxed to int.

When you only need to check the type of expression without declaring a new variable, you can utilize the discard _, as seen in the example below:

public static decimal CalculateToll(Vehicle vehicle) => vehicle switch
{
    Bus _ => 4.00m,
    Motor _ => 8.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
public static decimal CalculateToll(Vehicle vehicle) => vehicle switch
{
    Bus _ => 4.00m,
    Motor _ => 8.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
$vbLabelText   $csharpLabel

In this snippet, the _ serves as a placeholder for any type matching Vehicle.

Both declaration and type patterns ensure that expressions are non-null before pattern matching. You can check for non-null using a negated null constant pattern, as illustrated below:

if (inputVal is not null)
{
    // ...
}
if (inputVal is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

This negation ensures that inputVal is not null before proceeding with further operations.

By leveraging declaration and type patterns in your C# code, you can enhance readability, reduce lines of code, and express algorithms more effectively. These patterns provide a concise and expressive way to handle type-based logic and improve the maintainability of your codebase.

Constant Pattern

Constant patterns serve to verify if an expression result matches a specific constant value. Consider the following example:

public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
    1 => 2.0m,
    2 => 10.0m,
    3 => 25.0m,
    4 => 60.0m,
    0 => 0.0m,
    _ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
    1 => 2.0m,
    2 => 10.0m,
    3 => 25.0m,
    4 => 60.0m,
    0 => 0.0m,
    _ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
$vbLabelText   $csharpLabel

Here, the constant patterns check if visitorCount matches any of the specified constant values and return corresponding ticket prices.

In a constant pattern, you can employ various types of constant expressions, such as:

  1. Integer or floating-point numerical literals.
  2. Characters.
  3. String literals.
  4. Boolean values (true or false).
  5. Enum values.
  6. The name of a declared const field or local.
  7. null.

An expression of type Span<char> or ReadOnlySpan<char> can match constant strings.

To check for null, utilize a constant pattern like so:

if (inputVal is null)
{
    return;
}
if (inputVal is null)
{
    return;
}
$vbLabelText   $csharpLabel

Here, the pattern ensures that inputVal is null before proceeding with further operations.

You can also use a negated null constant pattern to ascertain non-null values:

if (inputVal is not null)
{
    // ...
}
if (inputVal is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

This pattern verifies that inputVal is not null, allowing for subsequent operations to be performed safely.

By incorporating constant patterns into your C# code, you can effectively handle scenarios where specific constant values need to be matched, improving code clarity and maintainability.

Relational Patterns

Relational patterns provide a means to compare expression results with constants. Consider the following example:

Console.WriteLine(Classify(20));  // output: Too high
Console.WriteLine(Classify(double.NaN));  // output: Unknown
Console.WriteLine(Classify(4));  // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 => "Too high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};
Console.WriteLine(Classify(20));  // output: Too high
Console.WriteLine(Classify(double.NaN));  // output: Unknown
Console.WriteLine(Classify(4));  // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 => "Too high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};
$vbLabelText   $csharpLabel

Here, the relational patterns compare the measurement against specific thresholds to determine its classification.

The Right-hand part of a relational pattern must be a constant expression, which can be of an integer, floating-point, char, or enum type. The <, >, <=, >= operators can be used on the left-hand side.

To match an expression result within a certain range, employ a conjunctive "and" pattern, as illustrated below:

Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12)));  // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12)));  // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12)));  // output: winter

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    >= 3 and < 6 => "spring",
    >= 6 and < 9 => "summer",
    >= 9 and < 12 => "autumn",
    12 or (>= 1 and <3) => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12)));  // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12)));  // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12)));  // output: winter

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    >= 3 and < 6 => "spring",
    >= 6 and < 9 => "summer",
    >= 9 and < 12 => "autumn",
    12 or (>= 1 and <3) => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
$vbLabelText   $csharpLabel

This excerpt describes how the conjunctive "and" pattern is utilized to ascertain the calendar season based on the month falling within specific ranges. It also mentions that relational patterns provide a concise and expressive means to compare expression results against constants, thus enhancing code clarity and maintainability.

Discard Pattern

The discard pattern, denoted by _, serves to match any expression, including null. Take the following example:

Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday));  // output: 5.0
Console.WriteLine(GetDiscountInPercent(null));  // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10));  // output: 0.0

static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
    DayOfWeek.Monday => 0.5m,
    DayOfWeek.Tuesday => 12.5m,
    DayOfWeek.Wednesday => 7.5m,
    DayOfWeek.Thursday => 12.5m,
    DayOfWeek.Friday => 5.0m,
    DayOfWeek.Saturday => 2.5m,
    DayOfWeek.Sunday => 2.0m,
    _ => 0.0m,
};
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday));  // output: 5.0
Console.WriteLine(GetDiscountInPercent(null));  // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10));  // output: 0.0

static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
    DayOfWeek.Monday => 0.5m,
    DayOfWeek.Tuesday => 12.5m,
    DayOfWeek.Wednesday => 7.5m,
    DayOfWeek.Thursday => 12.5m,
    DayOfWeek.Friday => 5.0m,
    DayOfWeek.Saturday => 2.5m,
    DayOfWeek.Sunday => 2.0m,
    _ => 0.0m,
};
$vbLabelText   $csharpLabel

In the discard pattern example above, it handles all the possible input values. All the days of the week are managed, and a default value is provided. With this, all possible values are handled. Discard pattern cannot be utilized as a pattern in an is expression or a switch statement. In such cases, a var pattern can be used with a discard, like var _, to match any expression. However, a discard pattern is permissible in a switch expression. For further details, please refer to the Discard pattern section of the feature proposal note.

Logical Patterns

Logical patterns in C# offer powerful tools for pattern matching, including negation, conjunction, and disjunction, which allow for more flexible and expressive matching conditions.

Negation (not pattern)

The negation pattern, represented by not, matches an expression when the negated pattern doesn't match the expression. This is particularly useful for checking if an expression is non-null, as demonstrated below:

if (input is not null)
{
    // ...
}
if (input is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

Here, the code block is executed if input is not null.

Conjunctive (and pattern)

The conjunctive pattern, using the and keyword, matches an expression when both patterns match the expression. This allows for combining multiple conditions, as illustrated by the following example:

Console.WriteLine(Classify(13));    // output: High
Console.WriteLine(Classify(-100));  // output: Too low
Console.WriteLine(Classify(5.7));   // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -40.0 => "Too low",
    >= -40.0 and < 0 => "Low",
    >= 0 and < 10.0 => "Acceptable",
    >= 10.0 and < 20.0 => "High",
    >= 20.0 => "Too high",
    double.NaN => "Unknown",
};
Console.WriteLine(Classify(13));    // output: High
Console.WriteLine(Classify(-100));  // output: Too low
Console.WriteLine(Classify(5.7));   // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -40.0 => "Too low",
    >= -40.0 and < 0 => "Low",
    >= 0 and < 10.0 => "Acceptable",
    >= 10.0 and < 20.0 => "High",
    >= 20.0 => "Too high",
    double.NaN => "Unknown",
};
$vbLabelText   $csharpLabel

In this example, the measurement is classified based on its value range.

Disjunctive (or pattern)

The disjunctive pattern, using the or keyword, matches an expression when either pattern matches the expression. This allows for handling multiple possible conditions, as shown below:

Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19)));  // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9)));  // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11)));  // output: spring

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    3 or 4 or 5 => "spring",
    6 or 7 or 8 => "summer",
    9 or 10 or 11 => "autumn",
    12 or 1 or 2 => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19)));  // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9)));  // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11)));  // output: spring

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    3 or 4 or 5 => "spring",
    6 or 7 or 8 => "summer",
    9 or 10 or 11 => "autumn",
    12 or 1 or 2 => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
$vbLabelText   $csharpLabel

Here, the calendar season is determined based on the month of the provided date.

These pattern combinators can be repeatedly used to create more complex and precise matching conditions, enhancing the flexibility and readability of your code.

Property Pattern

The property pattern enables the matching of an expression's properties or fields against nested patterns. An example of this can be seen in the following code snippet:

static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
$vbLabelText   $csharpLabel

Here, the property pattern ensures that the provided date corresponds to one of the specified conference days.

You can also incorporate a runtime type check and variable declaration within a property pattern, as shown below:

static string TakeFive(object input) => input switch
{
    string { Length: >= 5 } s => s.Substring(0, 5),
    string s => s,
    ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
    ICollection<char> symbols => new string(symbols.ToArray()),
    null => throw new ArgumentNullException(nameof(input)),
    _ => throw new ArgumentException("Unsupported input type."),
};
static string TakeFive(object input) => input switch
{
    string { Length: >= 5 } s => s.Substring(0, 5),
    string s => s,
    ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
    ICollection<char> symbols => new string(symbols.ToArray()),
    null => throw new ArgumentNullException(nameof(input)),
    _ => throw new ArgumentException("Unsupported input type."),
};
$vbLabelText   $csharpLabel

Here, the property pattern is used to handle strings and collections of characters, ensuring proper handling based on their properties.

Positional Pattern

In C#, the positional pattern allows for deconstructing an expression result and matching the resulting values against corresponding nested patterns. For instance:

public readonly struct Point
{
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) => (X, Y) = (x, y);
    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}

static string Classify(Point point) => point switch
{
    (0, 0) => "Origin",
    (1, 0) => "Positive X basis end",
    (0, 1) => "Positive Y basis end",
    _ => "Just a point",
};
public readonly struct Point
{
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) => (X, Y) = (x, y);
    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}

static string Classify(Point point) => point switch
{
    (0, 0) => "Origin",
    (1, 0) => "Positive X basis end",
    (0, 1) => "Positive Y basis end",
    _ => "Just a point",
};
$vbLabelText   $csharpLabel

In this example, the positional pattern is utilized to classify points based on their coordinates.

Furthermore, you can reference nested properties or fields within a property pattern, known as an extended property pattern, introduced in C# 10:

static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start.Y: 0 } or { End.Y: 0 };
static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start.Y: 0 } or { End.Y: 0 };
$vbLabelText   $csharpLabel

This feature enhances the flexibility of property patterns by allowing direct access to nested properties.

These patterns provide powerful mechanisms for handling complex data structures and improving the readability and expressiveness of your code.

Var Pattern

Var Pattern allows you to match any type. This can be particularly useful for capturing intermediate results within Boolean expressions or when multiple checks are required in switch case guards.

Here's an example demonstrating the use of var pattern in a Boolean expression:

static bool IsAcceptable(int id, int absLimit) =>
    SimulateDataFetch(id) is var results 
    && results.Min() >= -absLimit 
    && results.Max() <= absLimit;

static int [] SimulateDataFetch(int id)
{
    var rand = new Random();
    return Enumerable
               .Range(start: 0, count: 5)
               .Select(s => rand.Next(minValue: -10, maxValue: 11))
               .ToArray();
}
static bool IsAcceptable(int id, int absLimit) =>
    SimulateDataFetch(id) is var results 
    && results.Min() >= -absLimit 
    && results.Max() <= absLimit;

static int [] SimulateDataFetch(int id)
{
    var rand = new Random();
    return Enumerable
               .Range(start: 0, count: 5)
               .Select(s => rand.Next(minValue: -10, maxValue: 11))
               .ToArray();
}
$vbLabelText   $csharpLabel

In this example, SimulateDataFetch returns an array of integers, and the is var pattern captures the result in the results variable, allowing subsequent calculations based on its properties.

Additionally, var patterns can be utilized within switch expressions or statements for more concise and readable code. Here's an example using var pattern in switch case guards:

public record Point(int X, int Y);

static Point Transform(Point point) => point switch
{
    var (x, y) when x < y => new Point(-x, y),
    var (x, y) when x > y => new Point(x, -y),
    var (x, y) => new Point(x, y),
};

static void TestTransform()
{
    Console.WriteLine(Transform(new Point(1, 2)));  // output: Point { X = -1, Y = 2 }
    Console.WriteLine(Transform(new Point(5, 2)));  // output: Point { X = 5, Y = -2 }
}
public record Point(int X, int Y);

static Point Transform(Point point) => point switch
{
    var (x, y) when x < y => new Point(-x, y),
    var (x, y) when x > y => new Point(x, -y),
    var (x, y) => new Point(x, y),
};

static void TestTransform()
{
    Console.WriteLine(Transform(new Point(1, 2)));  // output: Point { X = -1, Y = 2 }
    Console.WriteLine(Transform(new Point(5, 2)));  // output: Point { X = 5, Y = -2 }
}
$vbLabelText   $csharpLabel

In this example, the var pattern (x, y) captures the coordinates of the point, allowing different transformations based on their values.

In a var pattern, the type of the declared variable is inferred from the compile-time type of the expression being matched against the pattern.

The var pattern provides a convenient way to handle various scenarios where the specific type of expression is not known in advance, improving code clarity and flexibility.

Introducing IronPDF Library

IronPDF Document Rendering is a library from Iron Software which specializes in PDF document generation. To get started, the first thing is to install the library from the NuGet Package manager or from the Visual Studio Package Manager.

# To install from the NuGet Package Manager Console
Install-Package IronPdf
# To install from the NuGet Package Manager Console
Install-Package IronPdf
SHELL

Below image shows how to install from Visual Studio Installation Guide.

C# Pattern Matching Expressions (How It Works For Developers): Figure 1 - Installing IronPDF with the NuGet package manager

In the below code, we shall see how to generate a simple PDF document:

using IronPdf;

namespace IronPatterns
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("-----------Iron Software-------------");
            var renderer = new ChromePdfRenderer(); // var pattern
            var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";

            // Declaration Pattern
            int? nullableX = 8;
            int y = 45;
            object boxedy = y;
            content += "<p>Declaration Pattern</p>";
            if (nullableX is int a && boxedy is int b)
            {
                Console.WriteLine(a + b); // output: 53
                content += $"<p>Output: {(a + b)}</p>";
            }

            // Relational patterns
            content += "<p>Relational patterns</p>";
            var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
            Console.WriteLine(season1);
            content += $"<p>2024, 2, 25: {season1}</p>";
            var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
            Console.WriteLine(season2);
            content += $"<p>2024, 5, 25: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</p>";

            var pdf = renderer.RenderHtmlAsPdf(content);
            pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF        
        }

        static string GetCalendarSeason(DateTime date) => date.Month switch
        {
            >= 3 and < 6 => "spring",
            >= 6 and < 9 => "summer",
            >= 9 and < 12 => "autumn",
            12 or (>= 1 and < 3) => "winter",
            _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
        };
    }
}
using IronPdf;

namespace IronPatterns
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("-----------Iron Software-------------");
            var renderer = new ChromePdfRenderer(); // var pattern
            var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";

            // Declaration Pattern
            int? nullableX = 8;
            int y = 45;
            object boxedy = y;
            content += "<p>Declaration Pattern</p>";
            if (nullableX is int a && boxedy is int b)
            {
                Console.WriteLine(a + b); // output: 53
                content += $"<p>Output: {(a + b)}</p>";
            }

            // Relational patterns
            content += "<p>Relational patterns</p>";
            var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
            Console.WriteLine(season1);
            content += $"<p>2024, 2, 25: {season1}</p>";
            var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
            Console.WriteLine(season2);
            content += $"<p>2024, 5, 25: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</p>";

            var pdf = renderer.RenderHtmlAsPdf(content);
            pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF        
        }

        static string GetCalendarSeason(DateTime date) => date.Month switch
        {
            >= 3 and < 6 => "spring",
            >= 6 and < 9 => "summer",
            >= 9 and < 12 => "autumn",
            12 or (>= 1 and < 3) => "winter",
            _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
        };
    }
}
$vbLabelText   $csharpLabel

Output

C# Pattern Matching Expressions (How It Works For Developers): Figure 2

Code Details

Here we are using IronPDF's ChromePdfRenderer class to save the HTML string into a PDF document. The output is saved to the "output.pdf" document.

Trial License

IronPDF can be used with a trial license obtained from the IronPDF Licensing Page. Provide an Email Id to generate a license key to be delivered to your email.

"IronPDF.LicenseKey": "<Your Key>"
"IronPDF.LicenseKey": "<Your Key>"
$vbLabelText   $csharpLabel

Place the License key in the appsettings.json file as shown above.

Conclusion

Pattern matching expressions in C# offer a powerful and flexible way to write conditional statements, type checks, and object deconstructions in a concise and readable manner. By leveraging pattern matching, developers can enhance the clarity and maintainability of their code while reducing boilerplate and redundancy. Whether it's type checking, switch statements, or deconstruction, pattern matching expressions provide a versatile toolset for tackling a wide range of programming tasks in C#.

In conclusion, mastering pattern matching expressions can greatly improve your C# programming skills, enabling you to write cleaner, more expressive code that is easier to understand and maintain. We've also covered IronPDF's HTML to PDF Generation abilities, which can be leveraged to generate PDF documents.

Frequently Asked Questions

What is pattern matching in C#?

Pattern matching in C# is a feature introduced in C# 7.0 that allows developers to perform concise and expressive conditional checks, type checking, and object deconstruction.

What are the benefits of using pattern matching in C#?

Pattern matching improves code readability, reduces lines of code, enhances maintainability, and allows for more expressive algorithms by simplifying complex conditional logic.

What are the types of pattern matching expressions in C#?

C# supports pattern matching through 'is' expressions, 'switch' statements, and 'switch' expressions.

What is a declaration and type pattern in C#?

Declaration and type patterns check the compatibility of an expression's runtime type with a given type and allow for declaring a new local variable if the match is successful.

How does a constant pattern work in C#?

Constant patterns verify if an expression result matches a specific constant value, such as integers, strings, or enum values, and execute corresponding logic based on the match.

What are relational patterns in C#?

Relational patterns allow expression results to be compared with constants using relational operators like <, >, <=, and >=, facilitating concise range checks.

What is the discard pattern in C#?

The discard pattern, denoted by '_', matches any expression, including null, and is useful for ignoring specific values in a switch expression.

How are property patterns used in C#?

Property patterns match an expression's properties or fields against nested patterns, enabling detailed checks of object structures.

What is IronPDF and how is it used?

IronPDF is a library from Iron Software that specializes in PDF document generation. It can be installed via NuGet and used to render HTML content as PDF documents in C# applications.

How does pattern matching enhance C# code maintenance?

Pattern matching clarifies code logic, making it easier to maintain and debug by clearly delineating logic blocks and reducing code redundancy.

Chipego
Software Engineer
Chipego has a natural skill for listening that helps him to comprehend customer issues, and offer intelligent solutions. He joined the Iron Software team in 2023, after studying a Bachelor of Science in Information Technology. IronPDF and IronOCR are the two products Chipego has been focusing on, but his knowledge of all products is growing daily, as he finds new ways to support customers. He enjoys how collaborative life is at Iron Software, with team members from across the company bringing their varied experience to contribute to effective, innovative solutions. When Chipego is away from his desk, he can often be found enjoying a good book or playing football.
< PREVIOUS
.NET Software Development (How It Works For Developers)
NEXT >
C# Internal (How It Works For Developers)