Pattern matching is a feature that allows you to implement method dispatch on properties other than the type of an object. Pattern matching is very useful when we want to create branching logic based on arbitrary types and values of the members of those types.
Object dispatch is a very common feature of object oriented programming wherein we identify objects based on their type and call appropriate method. Based on resolved type the method gets dispatched on appropriate type i.e. child or base. This feature is automatically implemented if we use concept of object oriented programming like Hiding and Overriding.
Problem occurs when there are multiple classes that our code uses and the classes are not related to each other. In that case the branching logic requires below steps to correctly dispatch method call to object:
- Identify type of object using various branching logic
- Cast to appropriate type if needed
- Call method on object
Example in C# 6.0:
Let’s say we have 2 classes FirstType and SecondType which are not related
class FirstType { public int Number { get; set; } } class SecondType { public int Number2 { get; set; } }
Let’s define a generator function which created object of either FirstType Or SecondType
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
/// <summary> /// Returns a collection of mixed objects which are not related and have differnt properties /// </summary> /// <returns></returns> IEnumerable<object> CreateTestData() { yield return new PatternMatching.FirstType() { Number = 1 }; yield return new PatternMatching.SecondType() { Number2 = 1 }; yield return new PatternMatching.FirstType() { Number = 1 }; yield return new PatternMatching.SecondType() { Number2 = 1 }; }
And here goes the code that calls the generator and calculate sum of all numbers encapsulated by returning objects.
private void btnPatternMatchingC6_Click(object sender, EventArgs e) { var sum = 0; //Get Mixed Data foreach (var item in CreateTestData()) { //Check if item is of type patternmatching.firsttype if (item is PatternMatching.FirstType) { //If yes cast to appropriate object to get access to property sum += (item as PatternMatching.FirstType).Number; } else if (item is PatternMatching.SecondType) { //If yes cast to appropriate object to get access to property sum += (item as PatternMatching.SecondType).Number2; } } }
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
As you can see first we identify the type of object using is keyword, then case that object to appropriate type so that we have a strongly type reference to the encapsulated Number variable.
With more unrelated objects the code become more and more complex.
Let’s try to resolve it using the new pattern matching enhancements.C# 7.0 support pattern matching using
- is keyword
- switch statement
Pattern matching using is keyword. Pretty short and concise
var sum = 0;
//Pattern matching with If statement and is keyword
var sum = 0; //Pattern matching with If statement and is keyword foreach (var item in CreateTestData()) { if (item is PatternMatching.FirstType firstType) { sum += firstType.Number; } else if (item is PatternMatching.SecondType secondType) { sum += secondType.Number2; } }
Pattern matching using switch statement
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
switch (item) { case PatternMatching.FirstType firstTypeUsingSwitch: sum += firstTypeUsingSwitch.Number; break; case PatternMatching.SecondType secondTypeUsingSwitch: sum += secondTypeUsingSwitch.Number2; break; default: break; }
switch statement now also support case for null values
switch (item) { case PatternMatching.FirstType firstTypeUsingSwitch: sum += firstTypeUsingSwitch.Number; break; case PatternMatching.SecondType secondTypeUsingSwitch: sum += secondTypeUsingSwitch.Number2; break; case null: break; default: break; }
switch statement also support When clause with case
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
switch (item) { Case FirstType firstTypeUsingSwitch when firstTypeUsingSwitch.Number > 0: sum += firstTypeUsingSwitch.Number; break; case PatternMatching.FirstType firstTypeUsingSwitch: sum += firstTypeUsingSwitch.Number; break; case PatternMatching.SecondType secondTypeUsingSwitch: sum += secondTypeUsingSwitch.Number2; break; case null: break; default: break; }
All code samples are available at my GitHub profile
I am a corporate trainer and solution architect and have a great team of software professionals. Please contact in case you need our services by sending email to contact@techprocompsoft.com. Here is our company website .