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