【发布时间】:2021-12-15 14:05:06
【问题描述】:
我有两个班级:
class DoorRequest : IRequest
{
string message;
}
class WindowRequest : IRequest
{
string message;
}
它们不相互继承,而是实现一个通用接口。 我想有一个通用的方法来创建这些类的实例。语义上等同于:
public static T MakeOpenRequest<T>() where T : IRequest
{
// If T is DoorRequest return new DoorRequest{message="please open the door"}
// If T is WindowRequest return new WindowRequest{message="please open the window"}
}
对我来说重要的是函数的结果是T,而不是IRequest。我可以扩展DoorRequest 和WindowRequest 的功能来提供实际的实现。 MakeOpenRequest 的实际逻辑可以想象得要复杂得多,因此编写一个普通的工厂会导致大量代码重复。该方法唯一关心的是它应该以命名方式创建某些类型的实例,即为每个类单独定义。
我怀疑常规构造函数在这里会有所帮助,因为几乎没有任何通用性可以利用。构造方法必须是静态的,所以我不能指望它们的多态性。
完成这项任务的最佳方法是什么?反射会作弊,但如果没有其他办法,那也没关系。
【问题讨论】:
-
您可以使用
Dictionary<Type, Func<IRequest>>集合来封装构造。这些Funcs 是如何产生的则是另一回事;您可以静态初始化这些或使用反射。 -
为什么界面上没有
SetOpenMessage()之类的方法?然后你可以只要求T有一个无参数的构造函数,调用那个方法,然后返回对象。 -
如果我写自己的请求
class FooRequest: IRequest { int foo; }怎么办?MakeOpenRequest<FooRequest>()会做什么? -
一旦你输入
if (T is something) {},你应该停下来,因为你做错了。 -
要利用Polymorphism,您应该能够针对
IRequest进行编程。例如,不要在 DoorRequest 上调用OpenDoor(),在 WindowRequest 上调用OpenWindow(),您应该在IRequest上调用Open()(或者更通用的Activate())(否则您将需要执行 @ 987654342@@BanksySan 指出的事情)。