c#循环泛型类型参数

时间:2017-04-09 19:54:02

标签: c# generics inheritance circular-dependency

我有2个泛型类:ManagerBase类和ChildBase类。 它们既抽象又有意为具体。 ManagerBase有一个ChildBase列表,这就是为什么我想让它成为通用的,所以CatalogManager:ManagerBase会有一个Catalogs列表。此外,每个目录都会引用它的'经理 - CatalogManager。

public class ManagerBase<T1> : ChildBase<???>
{
    public ManagerBase()
    {
        ChildObjects = new List<T1>();
    }

    public List<T1> ChildObjects { get; set; }
}

public class ChildBase<T1> : ManagerBase<???>
{
    public ChildBase(T1 parentMgr)
    {
        ParentMgr = parentMgr;
        ParentMgr.ChildObjects.Add(this);
    }

    public T1 ParentMgr { get; set; }
}

如何解决此对象模型?

感谢。

1 个答案:

答案 0 :(得分:1)

You have to define the base classes using the "curiously recursive" pattern:

public class ManagerBase<M, T1>
    where M : ManagerBase<M, T1>
    where T1 : ChildBase<M, T1>
{
    public ManagerBase()
    {
        ChildObjects = new List<T1>();
    }

    public List<T1> ChildObjects { get; set; }
}

public class ChildBase<T1, C>
    where T1 : ManagerBase<T1, C>
    where C : ChildBase<T1, C>
{
    public ChildBase(T1 parentMgr)
    {
        ParentMgr = parentMgr;
        ParentMgr.ChildObjects.Add((C)(object)this);
    }

    public T1 ParentMgr { get; set; }
}

Please note I've stuck with your usage of T1, but I think that's a bit confusing. I would have preferred to have used M and C for each.

The major downside with this is that you have to use the nasty double cast of (C)(object)this to make this work. C# doesn't allow full type safety on this pattern. A nefarious developer can create child classes that can break the pattern.

Then the concrete classes can be this:

public class CatalogManager : ManagerBase<CatalogManager, Catalog>
{
}

public class Catalog : ChildBase<CatalogManager, Catalog>
{
    public Catalog(CatalogManager parentMgr) : base(parentMgr)
    {
    }
}