Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

c#

What are pattern matching enhancements in C#?

Hammad Nasir

Overview

Pattern matching is the process in which an object is checked to ascertain that it has a specific shape. In C#, pattern matching can be implemented using if and switch constructs. However, we will discuss the recently introduced enhancements in pattern matching.

The if and is enhancements

Usually, when we need to perform an action based on the type of object, we pattern match it using if and is statements. The following code provides an example:

class Vehicle {
  public void start() {
    System.Console.WriteLine("The vehicle has started");
  }
}

class Car : Vehicle {
  public void drift() {
    System.Console.WriteLine("The car is drifting");
  }
}

class Bike : Vehicle {
  public void wheelstand() {
    System.Console.WriteLine("The bike is performing a wheelstand");
  }
}

class Program {
  static void Main() {
    Vehicle v = new Car();

    if (v is Bike) {
      ((Bike)v).wheelstand();
    } else if (v is Car) {
      ((Car)v).drift();
    } else {
      System.Console.WriteLine("Neither Car nor Bike");
    }
  }
}

In the example above, both the Bike and Car classes inherit the Vehicle class. Both classes have a different method defined inside. For the Car class, a drift method is defined, and for the Bike class, a wheelstand method is defined.

The code inside the Main method initializes a Vehicle variable v. We check if v is a Bike instance or a Car instance using the if and is constructs. Based on the type of v, we call the drift or wheelstand function.

However, a point to note is that we can’t call the drift or wheelstand functions on the v variable itself. The v variable has to be cast in the respective type before invoking the function. In line 26, this is done as: ((Car)v).drift().

The enhancement allows auto casting of the variable v. The following code provides an example of this enhancement:

class Vehicle {
  public void start() {
    System.Console.WriteLine("The vehicle has started");
  }
}

class Car : Vehicle {
  public void drift() {
    System.Console.WriteLine("The car is drifting");
  }
}

class Bike : Vehicle {
  public void wheelstand() {
    System.Console.WriteLine("The bike is performing a wheelstand");
  }
}

class Program {
  static void Main() {
    Vehicle v = new Car();

    if (v is Bike b) {
      b.wheelstand();
    } else if (v is Car c) {
      c.drift();
    } else {
      System.Console.WriteLine("Neither Car nor Bike");
    }
  }
}

Output

The car is drifting

In the example above, the variables b and c are created by typecasting v to the Bike or Car type if pattern matching is successful.

The switch enhancement

The switch statement conditionally executes the code based on the value of the specified variable. The following code provides an example:

class Program {
  static void Main() {
    int x = 3;
    
    switch (x) {
      case 1:
        System.Console.WriteLine("Value of x is 1");
        break;
      case 2:
        System.Console.WriteLine("Value of x is 2");
        break;
      case 3:
        System.Console.WriteLine("Value of x is 3");
        break;
      default:
        System.Console.WriteLine("No match found!");
        break;
    }
  }
}

In the example above, case 3 in line 12 matches, since the value of x is 3.

However, the switch statement only works on numeric or string types, and the cases present in the construct can only be literals. The new enhancement allows the switch statement to be used on any type. The following code provides an example:

class Vehicle {
  public void start() {
    System.Console.WriteLine("The vehicle has started");
  }
}

class Car : Vehicle {
  public void drift() {
    System.Console.WriteLine("The car is drifting");
  }
}

class Bike : Vehicle {
  public void wheelstand() {
    System.Console.WriteLine("The bike is performing a wheelstand");
  }
}

class Program {
  static void Main() {
    Vehicle v = new Car();

    switch (v) {
      case Bike b:
        b.wheelstand();
        break;
      case Car c:
        c.drift();
        break;
      default:
        System.Console.WriteLine("Neither Car nor Bike");
        break;
    }
  }
}

The above code presents the Vehicle example using a switch statement. Similar to how v was cast in the if/is example, the case clause also allows this.

The when clause in a switch statement

The when clause can now be used to add additional conditions in the case statement. Following is an example:

class Vehicle {
  public string company;
  public void start() {
    System.Console.WriteLine("The vehicle has started");
  }
}

class Car : Vehicle {
  public void drift() {
    System.Console.WriteLine("The car is drifting");
  }
}

class Bike : Vehicle {
  public void wheelstand() {
    System.Console.WriteLine("The bike is performing a wheelstand");
  }
}

class Program {
  static void Main() {
    Vehicle v = new Car();
    v.company = "Honda";

    switch (v) {
      case Bike b:
        b.wheelstand();
        break;
      case Car c when c.company = "Toyota":
        System.Console.WriteLine("The car is of Toyota company");
        c.drift();
        break;
      case Car c when c.company = "Honda":
        System.Console.WriteLine("The car is of Honda company");
        c.drift();
        break;
      default:
        System.Console.WriteLine("Neither Car nor Bike");
        break;
    }
  }
}

Output

The car is of Honda company
The car is drifting

The example above extends the previous example. A new string variable (company) is defined inside the Vehicle class. The case statements in lines 29 and 23 use the when clause to check whether the value of company is Toyota or Honda.

RELATED TAGS

c#

CONTRIBUTOR

Hammad Nasir
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring