考虑以下情况:
可以Categories
;来自Children
的{{1}};在某个地方,必须有一个看起来像这样的方法:
Categories
ChildType[] Get(ParentType parent) { ... }
不是来自ChildType
;它们是如此命名的,因为这种方法是一种工厂方法,可以根据父项的ID获取子项。
目前我的内容如下:
ParentType
然后我会这样叫工厂:
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 { }
这样做的目的是 - 给定一些具有ID的强类型父实例,转到具有该ID的Web服务,然后反序列化新的子实例。
这会让我的口味不好。在我看来,CatFactory<ChildCategoryA, ParentCategoryA>.Get(someparent);
应该知道其父级是ChildCategoryA
,而且应该能够调用ParentCategoryA
。这当然可以通过为子进程的每个实现定义ChildCategoryA.Get(someparent)
来实现,但这需要大量的重复代码。
那么 - 最好的方法是什么?单独的工厂类,还是没有?
答案 0 :(得分:3)
我发现这个问题有点令人困惑。这就是我认为你想要做的事情:
编写一个静态方法,给定一个Category对象,知道如何查找指定类型的该类别的所有子级。
如果这是正确的,那么我建议使用扩展方法:
static class CategoryExtensions
{
public static T[] GetChildren<T>(this Category parent)
where T : Category, new()
{
// Do whatever...
}
}
然后,给定任何类别对象,您可以写:
ChildCategory[] children = parent.GetChildren<ChildCategory>();
答案 1 :(得分:0)
一个想法是使用反射在运行时定位所需的类型。这很慢,一般不推荐;如果你这样做,最好缓存结果,以避免反复多次。
不涉及反射的替代方法是让孩子们将自己添加到静态初始化器中的某种注册表中 - 这样你就可以轻松地编写所需的Get<TChild, TParent>
方法,同时保持关系“本地”的关系
就个人而言,如果所有这些关系在编译时都是已知的,我只需将它们连接在一个地方,并省去了记住所有内容定义的麻烦。 =)