Lädt...


🔧 Mastering C# Switch Expressions and Pattern Matching: A Practical Guide


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

Introduction

As seasoned C# developers, we've all used switch statements to make decisions based on values. C# 7.0 introduced pattern matching, and C# 12 took it a step further with switch expressions. This powerful combination enhances code readability, maintainability, and expressiveness, especially when dealing with complex logic and diverse input types.

Demystifying Switch Expressions and Pattern Matching

Switch Expressions

Switch expressions are a concise and expressive alternative to traditional switch statements. They allow you to return a value directly from a case, making them ideal for scenarios where you need a result based on the matched pattern. Here's the basic syntax:

expression switch
{
    pattern1 => value1,
    pattern2 => value2,
    // ... more patterns
    _ => default  // Optional default case
}
  • expression: The value to be matched against the patterns.
  • pattern: A pattern that specifies the conditions for a case to match.
  • value: The value to return if the expression matches the pattern.
  • _: The discard pattern, used as a catch-all for unmatched cases.
  • default: An optional default case that executes if no pattern matches.

Pattern Matching

Pattern matching is the core concept at play here. It allows you to compare an expression against different patterns and take corresponding actions. C# supports a rich set of patterns, including:

  • Constant Pattern: Matches against a specific constant value.

    dayOfWeek switch
    {
        DayOfWeek.Monday => "Start of the week blues",
        DayOfWeek.Friday => "TGIF!",
        // ... other weekdays
    }
    
  • Type Pattern: Matches against a specific type.

    object obj = "...";
    if (obj is string str)
    {
        Console.WriteLine($"String value: {str}");
    }
    else if (obj is int i)
    {
        Console.WriteLine($"Integer value: {i}");
    }
    
  • Relational Pattern: Matches based on a relational operator (<, >, <=, >=, ==, !=).

    int age = 25;
    switch (age)
    {
        case < 18:
            Console.WriteLine("Not eligible to vote");
            break;
        case >= 18:
            Console.WriteLine("Eligible to vote");
            break;
    }
    
  • Property Pattern: Matches based on the value of a property.

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    
    Person person = new Person { Name = "Alice", Age = 30 };
    switch (person)
    {
        case Person p when p.Age >= 18:
            Console.WriteLine($"{p.Name} is an adult");
            break;
        default:
            Console.WriteLine($"{person.Name} is not an adult");
            break;
    }
    
  • Discard Pattern (_): Captures a value but doesn't use it (useful for cases where the value isn't needed).

    switch (Console.ReadLine())
    {
        case _:  // Handle any input
            Console.WriteLine("Input received");
            break;
    }
    
  • Logical AND (&), OR (|), and NOT (!): Combine patterns for complex matching.

    string input = "...";
    switch (input)
    {
        case string s when s.StartsWith("Hello") && s.EndsWith("World"):
            Console.WriteLine("Greeting received");
            break;
        case string s when s.Length > 10 | s.Contains("!"):
            Console.WriteLine("Long or emphatic input");
            break;
    }
    

Real-World Use Cases of C# Switch Expressions and Pattern Matching

In the realm of practical C# development, switch expressions and pattern matching shine in various scenarios. Let's delve into some compelling examples:

1. Data Validation and Processing

  • Robust Input Handling: When dealing with user input, you can leverage switch expressions to ensure data integrity. Validate input types and extract meaningful values:
  string input = Console.ReadLine();
  switch (input)
  {
      case int i:
          Console.WriteLine($"Integer value: {i}");
          // Perform integer-specific operations
          break;
      case double d:
          Console.WriteLine($"Double value: {d}");
          // Perform double-specific operations
          break;
      case string s when s.Length > 0:  // Handle non-empty strings
          Console.WriteLine($"String value: {s}");
          // Perform string-specific operations
          break;
      default:
          Console.WriteLine("Invalid input. Please enter a number or a string.");
          break;
  }
  • Complex Data Structures: When working with complex data structures like enum or custom types, pattern matching allows for concise and readable validation and processing:
  enum FileOperation
  {
      Create,
      Read,
      Update,
      Delete
  }

  FileOperation operation = GetFileOperationFromUser();  // Function to get user input

  switch (operation)
  {
      case FileOperation.Create:
          CreateFile();
          break;
      case FileOperation.Read:
          ReadFile();
          break;
      case FileOperation.Update: when CanUpdateFile():  // Conditional update
          UpdateFile();
          break;
      case FileOperation.Delete:
          DeleteFile();
          break;
      default:
          Console.WriteLine("Invalid operation selected.");
          break;
  }

2. State Management and Flow Control

  • Encapsulated State Machines: Simplify state management logic by utilizing switch expressions for transitions based on events or conditions:
  enum GameState
  {
      StartMenu,
      Playing,
      GameOver
  }

  GameState currentState = GameState.StartMenu;

  while (true)
  {
      GameState nextState = currentState;
      switch (currentState)
      {
          case GameState.StartMenu:
              if (HandleStartMenuInput())
              {
                  nextState = GameState.Playing;
              }
              break;
          case GameState.Playing:
              if (IsGameOver())
              {
                  nextState = GameState.GameOver;
              }
              // ... handle game logic
              break;
          case GameState.GameOver:
              if (HandleGameOverInput())
              {
                  nextState = GameState.StartMenu; // Or other options
              }
              break;
      }

      currentState = nextState;
  }

3. Configuration Parsing and Deserialization

  • Flexible Configuration Handling: When parsing configuration files or deserializing data, switch expressions offer a clean way to handle different data formats or missing values:
  IConfiguration config = LoadConfiguration();

  switch (config)
  {
      case IConfigurationSection section:
          string value = section.Value;  // Access configuration values
          break;
      case null:
          Console.WriteLine("Configuration not found.");
          break;
      default:
          Console.WriteLine("Invalid configuration format.");
          break;
  }

By effectively combining switch expressions and pattern matching, you can create more readable, maintainable, and expressive code in various C# applications.

...

🔧 Mastering C# Switch Expressions and Pattern Matching: A Practical Guide


📈 81.04 Punkte
🔧 Programmierung

🔧 C# Pattern Matching Inside Out: Kompakter und prägnanter C#-Code durch Pattern Matching


📈 58.52 Punkte
🔧 Programmierung

🔧 Mastering Pattern-Matching in Elixir


📈 38.97 Punkte
🔧 Programmierung

🔧 A Comprehensive Guide to Pattern Matching in Python


📈 34.9 Punkte
🔧 Programmierung

🔧 Pattern Matching for Switch in Java 21


📈 34.75 Punkte
🔧 Programmierung

🔧 Exploring the Power of Pattern Matching with Switch in Java 21


📈 34.75 Punkte
🔧 Programmierung

🕵️ angular-expressions up to 1.1.1 expressions.compile injection


📈 34.56 Punkte
🕵️ Sicherheitslücken

🔧 Mastering Zabbix Regular Expressions: A Comprehensive Guide


📈 32.64 Punkte
🔧 Programmierung

🔧 Implementing Horizontally Scalable Transactional Outbox Pattern with .NET 8 and Kafka: A Practical Guide


📈 31.95 Punkte
🔧 Programmierung

🔧 Debugging Tips and Tricks for Python Structural Pattern Matching


📈 30.92 Punkte
🔧 Programmierung

🔧 Elixir pattern matching - save your time and friendly with our thinking way!


📈 30.92 Punkte
🔧 Programmierung

🔧 The Power of Small Tweaks: Java 17's Flow Scoping and Pattern Matching Unveiled


📈 30.92 Punkte
🔧 Programmierung

🔧 Pattern Matching and Records Changes in Java 21: Every Java Developer Must Know


📈 30.92 Punkte
🔧 Programmierung

🔧 Exploring Java Record Patterns and Pattern Matching


📈 30.92 Punkte
🔧 Programmierung

🔧 Implementing Saga Pattern in Microservices with .NET Core: A Practical Guide


📈 30.28 Punkte
🔧 Programmierung

🔧 Proxy Pattern: A Practical Guide to Smarter Object Handling


📈 30.28 Punkte
🔧 Programmierung

🔧 Real-Time Notifications with the Observer Pattern: A Practical Guide


📈 30.28 Punkte
🔧 Programmierung

🔧 Practical LLM - Matching and Ranking by Erik Schmiegelow, CEO of Hivemind Technologies AG


📈 30.25 Punkte
🔧 Programmierung

🔧 How Do I Make RegEx Optional? Specify Optional Pattern in Regular Expressions


📈 29.94 Punkte
🔧 Programmierung

📰 YARA – Pattern Matching Tool For Malware Analysis


📈 29.26 Punkte
📰 IT Security Nachrichten

📰 YARA – Pattern Matching Tool For Malware Analysis


📈 29.26 Punkte
📰 IT Security Nachrichten

🐧 Bash script function 'ren' which rename in batch any file name matching the pattern of nearly/emulated PCRE


📈 29.26 Punkte
🐧 Linux Tipps

🎥 HPR2888: Pattern matching in Haskell


📈 29.26 Punkte
🎥 Podcasts

🔧 C# Language Highlights: Pattern Matching Basics | On .NET


📈 29.26 Punkte
🔧 Programmierung

📰 Programmiersprache: Ruby 2.7 führt Pattern Matching ein


📈 29.26 Punkte
📰 IT Nachrichten

📰 After 19 Years, Python May Finally Get a Pattern Matching Syntax


📈 29.26 Punkte
📰 IT Security Nachrichten

🐧 [$] "Structural pattern matching" for Python, part 1


📈 29.26 Punkte
🐧 Linux Tipps

🐧 [$] "Structural pattern matching" for Python, part 2


📈 29.26 Punkte
🐧 Linux Tipps

🐧 [$] Python structural pattern matching morphs again


📈 29.26 Punkte
🐧 Linux Tipps

🐧 Pattern matching accepted for Python


📈 29.26 Punkte
🐧 Linux Tipps

📰 Golang Approves Generics, While Python Accepts Pattern-Matching Proposals


📈 29.26 Punkte
📰 IT Security Nachrichten

🔧 C# Language Highlights: Tuple Pattern Matching | On .NET


📈 29.26 Punkte
🔧 Programmierung

🐧 svlogd pattern matching doesn't seem to work as documented


📈 29.26 Punkte
🐧 Linux Tipps

🐧 [$] An overview of structural pattern matching for Python


📈 29.26 Punkte
🐧 Linux Tipps

matomo