Understanding Pattern Matching In C# 7.0

We are aware of is-Expression where we can use is keyword to verify the given type. In C# 7.0, this has been extended to constant, type, and var patterns as well. Let's dig into each of the patterns here. 

Pattern Matching with constants 

Earlier in is-Expressions, we used to match the variable types but now, we can even verify and validate for constants too. See the code below. 

  1. public void PatternMatchingWithConstants() {  
  2.     int age = 50;  
  3.     if (age is 50) {  
  4.         //Do write some logic here   
  5.     }  
  6. }  

As observed in the above code, we are validating a constant value using is-Expression in an "if" block. 

Pattern Matching with Types 

As we see in the above code, we validated the constants. Similarly, we can validate the type of a given variable in the "if" block as shown below. 

  1. public void PatternMatchingWithType() {  
  2.     object age = 50;  
  3.     if (age is int) {  
  4.         int myage = (int) age;  
  5.         //Do write some logic here   
  6.     }  
  7. }  

In addition to this, we are given other flexibility here. As observed in the above code, we perform two actions. First, we are verifying if the age type is int or not; and once it is true, then we are type casting it to another variable. Now, we can do these two actions in a single step, i.e., validating and assigning to a variable the if condition success. 

  1. object age = 50;  
  2. if (age is int myage) {  
  3.     //Do write some logic here   
  4. }  

In the above code, the age will be verified as type int or not. Then,  it will be type-casted and assigned to myage in a single step. 

Type pattern matching can also be applied at inheritance. It will verify whether the given class object is inherited by a base class or not, as shown below. 

  1. public class Animal {  
  2.     public string Name {  
  3.         get;  
  4.         set;  
  5.     }  
  6. }  
  7. public class Dog: Animal {}  
  8. public class Cat: Animal {}  
  9. public class Main {  
  10.     public void GetAnimal() {  
  11.         Dog dog = new Dog();  
  12.         if (dog is Animal animal) {  
  13.             //Do write some logic here   
  14.         }  
  15.     }  
  16. }  

The above code is self-explanatory. Here, we can even verify if the given object is of type base class or not.

The point to be noted here is that the match will fail when an object is set to null, even if the type matches. 

  1. public void GetAnimal() {  
  2.     Dog dog = null;  
  3.     if (dog is Dog) //returns false   
  4.     {  
  5.         //Do write some logic here   
  6.     }  
  7. }  

Another point to note is, we can use this feature in any logical expressions too, as shown below. 

  1. public void GetAnimal() {  
  2.     Dog dog = new Dog();  
  3.     if (dog is Animal animal && animal.Name == "Dog") {  
  4.         //Do write some logic here   
  5.     }  
  6. }  

Pattern Matching with Var 

Variable Pattern is used similar to the constants and type but here, the is-Expression will always return true and typecast to the given type. 

  1. public void GetAnimalWithVar() {  
  2.     Dog dog = new Dog() {  
  3.         Name = "Dog"  
  4.     };  
  5.     Cat cat = new Cat() {  
  6.         Name = "Cat"  
  7.     };  
  8.     PrintAnimalName(dog);  
  9.     PrintAnimalName(cat);  
  10.     //Local functions in C# 7.0   
  11.     void PrintAnimalName(Animal obj) {  
  12.         if (obj is  
  13.             var animal) //Always returns true   
  14.         {  
  15.             Console.WriteLine(animal.Name);  
  16.         }  
  17.     }  
  18. }  

As observed, every time it calls the PrintAnimalName() method, it will return the respective given names to each provided object. 

Hope, this explanation gives you the concept. 

You can see the complete code here on GitHub.