【发布时间】:2020-12-08 21:52:21
【问题描述】:
想象有某种工厂方法称为GetInstance(),它构建一个类并返回一个基实例;
abstract class BaseClass { }
class Type1 : BaseClass { }
class Type2 : BaseClass { }
BaseClass GetInstance()
{
// returns either Type1 or Type2 instance
}
我想执行将具体类实例而不是基类作为参数的两种方法之一
void DoSomething(Type1 instance)
{
// do something with type 1 instance
}
void DoSomething(Type2 instance)
{
// do something with type 2 instance
}
这样做的丑陋方式显然打破了开闭原则,就是遍历所有可能的类型,调用适当的方法
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;
}
}
一种更通用的方法是使用反射来查找可以采用类实例物理类型的所有方法
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});
}
我只是想知道,这是一个好的模式吗?有没有比使用反射更好、更受认可的方式来打开子类型?
【问题讨论】:
-
为什么不重载
GetInstance以返回特定类型? -
寻找“C#中的双重调度”
-
策略模式可以让你在不破坏开/关原则的情况下切换案例。
-
@JohnathanBarclay C# 不支持返回类型协方差 - stackoverflow.com/a/5709191/1069178
-
@Steztric 重载不覆盖。不过,这是一个糟糕的选择。我的意思是使用单独的方法返回特定类型,重载或其他。
标签: c# reflection polymorphism