CodeBlanks Logo Icon CodeBlanks

Pattern matching for polymorphism

C# course · Intermediate · Lesson 62/116

Learn polymorphic dispatch with switch expressions and type patterns.

switch expressions and type patterns

The modern C# switch expression with type patterns performs polymorphic dispatch at the expression level. Code that handles an Animal by its runtime type becomes a single expression.

Example: string sound = animal switch { Dog d => "Woof", Cat c => "Meow", _ => "?" };. Here Dog d is a type pattern: on match, the variable d binds to the object. _ is the default discard arm. Because a switch expression produces a value, it can be assigned to a variable.

Extra conditions with when

Sometimes the type alone is not enough; you need an extra condition inside the same type. For that you use a when clause. An arm like Dog d when d.Age > 5 catches only dogs older than five.

The when clause filters after the type pattern matches. This lets you write finer discriminating arms. Order matters: arms are tried top to bottom, and the first match runs. Always put the default arm last. Otherwise the compiler warns you.

Exercise Produce sounds with a switch expression

Define an Animal class. Define Dog : Animal and Cat : Animal. In Program write static string Sound(Animal a) using a switch expression: return "Woof" for Dog, "Meow" for Cat, "?" for the default. In Main call Sound with a Dog, a Cat, an Animal and print each result.

Show example solution
Write static string Sound(Animal a) { return a switch { Dog d => "Woof", Cat c => "Meow", _ => "?" }; }. In Main add Console.WriteLine(Sound(new Dog())); Console.WriteLine(Sound(new Cat())); Console.WriteLine(Sound(new Animal()));
Example solution:
using System;

class Animal { }
class Dog : Animal { }
class Cat : Animal { }

class Program
{
    static string Sound(Animal a)
    {
        return a switch
        {
            Dog d => "Woof",
            Cat c => "Meow",
            _ => "?"
        };
    }

    static void Main()
    {
        Console.WriteLine(Sound(new Dog()));
        Console.WriteLine(Sound(new Cat()));
        Console.WriteLine(Sound(new Animal()));
    }
}

Test yourself

  1. Which is the default arm in a switch expression?

    var s = a switch {
        Dog d => "Woof",
        _ => "?"
    };
    • default =>
    • else =>
    • null =>
    • _ =>
    Show answer

    _ => — Correct. _ (discard) is the default arm of a switch expression.

  2. Bind a variable with a type pattern

    if (animal ____ Dog d) { d.Bark(); }
    Show answer
    if (animal is Dog d) { d.Bark(); }
  3. Match each pattern piece to its meaning

    switch
    Branches by expression
    =>
    Arrow expression
    is
    Tests a type pattern
    when
    Adds a filter

All lessons in Intermediate