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.
if
and is
enhancementsUsually, 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"); } } }
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.
switch
enhancementThe 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.
when
clause in a switch
statementThe 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; } } }
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
CONTRIBUTOR
View all Courses