How to Perform Polymorphism on Object from Different Classes in C#

Published

This little trick comes from MBeliou, so give him a follow if this helps you out.

C# is a typed langage so in Unity we can set objects from different classes inheriting from a base class into the same field.

Here’s an example to show what I mean:


public abstract class BaseClass {
    public abstract void DoSomething();

}


public class ChildA: BaseClass {
    public override void DoSomething() {
        Debug.Log("ChildA - DoSomething");
    }

    public void DoSomethingChildA() {
        Debug.Log("ChildA - DoSomethingChildA");

    }

}

public class ChildB: BaseClass {
    public override void DoSomething() {
        Debug.Log("ChildB - DoSomething");
    }

    public void DoSomethingChildB() {
        Debug.Log("ChildB - DoSomethingChildB");

    }


}

Here we have a base class called “BaseClass” and 2 children class (ChildA and ChildB) which have a function in common and another class specific function.

Now let’s imagine that we have a controller that has a field which references an object of type BaseClass, but we want to be able to access the children specific functions of ChildA and ChildB. The problem is here is that, by default, C# will not be able to cast the children automatically: you would have to be able to get the type information of the element, and then perform casting.

Performing type comparison like this can be a tricky business and should usually be avoided. Thankfully, C# is actually capable of performing this automated polymorphism, it’s just that this functionality is hidden! You only need to execute a switch statement on your object to perform this task.

This solution needs you to write a little dispatch function but that’s no big deal. Let’s see how our controller would look like:


public class MyController: MonoBehaviour {

    public BaseClass mMyBaseClassObject;


    public void RunChildMethod() {
        switch(mMyBaseClassObject) {
            case ChildA childA:
                childA.DoSomethingChildA();
                break;
            case ChildB childB:
                childB.DoSomethingChildB();
                break;
            default:
                break;
        }
    }
}

If you try it out, you’ll realize that C# is indeed capable of using the correct method, without any need for any messy type comparisons.

Once again, give a follow to MBeliou if this helped you out!