mercredi 19 août 2020

C# - Polymorphic method selection from base type

Imagine there is some kind of factory method called GetInstance() that builds a class and returns a base instance;

abstract class BaseClass { }

class Type1 : BaseClass { }

class Type2 : BaseClass { }

BaseClass GetInstance()
{
    // returns either Type1 or Type2 instance
}

I want to execute one of two methods that takes the concrete class instance as a parameter, not the base class

void DoSomething(Type1 instance)
{
    // do something with type 1 instance
}

void DoSomething(Type2 instance)
{
    // do something with type 2 instance
}

The ugly way of doing it, that clearly breaks the open-closed principle, is to just iterate through all the possible types, calling the appropriate method

void GetAndInvokeBad()
{
    BaseClass instance = GetInstance();
    
    // Sucky way of selecting the right polymorphic method
    switch (instance)
    {
        case Type1 t1instance:
            DoSomething(t1instance);
            break;
        case Type2 t2instance:
            DoSomething(t2instance);
            break;
    }
}

A more generic way of doing it would be to use reflection to look up all the methods that can take the class instance physical type

void GetAndInvokeGood()
{
    BaseClass instance = GetInstance();

    var method = GetType().GetMethods()
        .Where(m => m.Name == "DoSomething")
        .First(m => m.GetParameters()[0].ParameterType == instance.GetType());

    method.Invoke(this, new object[] {instance});
}

I'm just wondering, is this a good pattern? Is there a better and more recognised way of switching on the child type rather than using reflection?





Aucun commentaire:

Enregistrer un commentaire