2

考虑以下情况:

可以有CategoriesChildren源自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()为孩子的每个实现定义一个来实现,但这需要大量的重复代码。

那么 - 最好的方法是什么?单独的工厂类,还是没有?

4

2 回答 2

3

我觉得这个问题有点令人困惑。这就是我认为你想要做的:

编写一个静态方法,给定一个 Category 对象,该方法知道如何找到指定类型的该类别的所有子项。

如果这是正确的,那么我会建议一个扩展方法:

static class CategoryExtensions
{
    public static T[] GetChildren<T>(this Category parent)
        where T : Category, new()
    {
        // Do whatever...
    }
}

然后,给定任何类别对象,您可以编写:

ChildCategory[] children = parent.GetChildren<ChildCategory>();
于 2013-01-09T20:47:19.887 回答
0

一种想法是使用反射在运行时定位所需的类型。这很慢,通常不推荐;如果这样做,明智的做法是缓存结果以避免多次反映。

不涉及反射的另一种方法是让孩子将自己添加到静态初始化程序中的某种注册表中 - 这样您就可以轻松编写所需的Get<TChild, TParent>方法,同时保持“本地”关系的知识。

就个人而言,如果在编译时就知道所有这些关系,我只需将它们全部连接到一个地方,就可以省去记住所有定义的位置的麻烦。=)

于 2013-01-09T21:29:57.640 回答