【发布时间】:2013-01-09 19:53:36
【问题描述】:
考虑以下情况:
可以有Categories; Children 派生自 Categories;在某个地方,必须有一个看起来像这样的方法:
ChildType[] Get(ParentType parent) { ... }
ChildType 不是从ParentType 派生的;之所以这样命名,是因为该方法是一种工厂方法,用于根据父母的 ID 获取孩子。
目前我有这样的东西:
static class CatFactory<ChildType, ParentType> : Category
where ParentType: Category
where ChildType: Category, new()
{
public static ChildType[] Get(string catname, ParentType parent)
{
// ...
}
}
class ParentCategoryA : Category { }
class ParentCategoryB: Category { }
class ChildCategoryA: Category { }
class ChildCategoryB: Category { }
然后我会这样调用工厂:
CatFactory<ChildCategoryA, ParentCategoryA>.Get(someparent);
这样做的目的是 - 给定一些具有 ID 的强类型父实例,转到具有该 ID 的 Web 服务,然后反序列化一个新的子实例。
这在我嘴里留下了不好的味道。在我看来ChildCategoryA 应该知道它的父级是ParentCategoryA,并且应该能够调用ChildCategoryA.Get(someparent)。这当然可以通过为孩子的每个实现定义一个static Get() 来实现,但这需要大量的重复代码。
那么 - 最好的方法是什么?单独的工厂类,还是没有?
【问题讨论】:
-
你能定义一个通用的
Category<TParentType>吗?所以你会有class ChildCategoryA : Category<ParentCategoryA>? (反过来,Category<TParentType>可能继承自非泛型Category基类,如果它对您的 API 有意义) -
不能有
Category<TParentType>,因为有些类别没有父级。但是,我可以有类似ChildCategory<TParentType>的东西。但我不知道这会让我走多远——我怎么会有一个static Get()? -
您可以定义一个密封的内部构造函数
RootCategory类型作为虚拟对象来指示根类别。至于Get... uhhhh 井类型可以在第一次使用时注册自己(静态构造函数)?或者您可以通过应用程序启动时的反射进行搜索以找到所有类型? -
我认为
public static ChildType[] Get(string catname)会是一个更简洁的签名。ParentType将从CatFactory的类型中推断出来。 (我没有方便的编译器来测试这个。) -
@neontapir
Get()需要传递一个父实例来获取一个子实例。它不仅取决于父级的类型,还取决于父级字段之一的值。