泛型和父/子架构

时间:2011-03-22 02:58:18

标签: c# generics parent-child

我正在构建一个具有可继承泛型和父子关系的架构。 我有一个主要问题:我不能让孩子和父母都知道对方的类型,只有两个中的一个。

我需要孩子和父母都知道彼此的类型。

场景1 :父级知道子级类型,但子级只知道具有通用子级的通用父级。

public class Child
{
    public Parent<Child> Parent;
}

public class Parent<TChild>
    where TChild : Child
{
    public List<TChild> Children;
}

场景2 :Child知道父类型,但父级只知道具有通用父级的通用子级。

public class Child<TParent>
    where TParent : Parent
{
    public TParent Parent;
}

public class Parent
{
    public List<Child<Parent>> Children;
}

场景3 :乌托邦但无法实现的场景:

public class Child<TParent>
    where TParent : Parent
{
    public TParent Parent;
}

public class Parent<TChild>
    where TChild : Child
{
    public List<TChild> Children;
}

当然,方案3不会编译,因为Parent和Child采用第二种通用​​类型他们自己的类型,但我不能(或者至少不知道如何) !)指定它是自己的类型。

我在这里陷入某种无限循环/递归/抛球,请在我淹死之前帮助我。

祝你好运。

编辑:如果我不清楚,我可以引用我的类型是,但是如果用户将Child派生到FooChild,并访问FooChild父级的子节点,那么这些只会是Child ,而不是FooChild,应该如此。

方案1的失败示例

public class Child
{
    public Parent<Child> Parent;
}

public class Parent<TChild>
    where TChild : Child, new()
{
    public List<TChild> Children;
}

public class FooChild : Child
{
    public int Required;

    public void Bar()
    {
        foreach (Child child in this.Parent.Children)
        {
            int x = child.Required; // cannot be accessed!
        }
    }
}

方案2的失败示例

public class Child<TParent>
    where TParent : Parent
{
    public TParent Parent;
}

public class Parent
{
    public List<Child<Parent>> Children;
}

public class FooChild : Child<Parent>
{
    public int Required;

    public void Bar()
    {
        foreach (Child<Parent> child in this.Parent.Children)
        {
            int x = child.Required; // cannot be accessed!
        }
    }
}

1 个答案:

答案 0 :(得分:17)

你当然可以做你所要求的。像这样定义你的类:

public abstract class Child<P, C>
    where P : Parent<P, C>
    where C : Child<P, C>
{
    public P Parent { get; set; }
}

public abstract class Parent<P, C>
    where P : Parent<P, C>
    where C : Child<P, C>
{
    public List<C> Children = new List<C>();
}

然后你可以像这样定义你的具体类:

public class Cat : Parent<Cat, Kitten>
{
}

public class Kitten : Child<Cat, Kitten>
{
}

public class Dog : Parent<Dog, Puppy>
{
}

public class Puppy : Child<Dog, Puppy>
{
}

现在您拥有完全类型的父子关系。此代码现在有效:

var fluffy = new Cat();
var fluffette1 = new Kitten() { Parent = fluffy };
var fluffette2 = new Kitten() { Parent = fluffy };

fluffy.Children.Add(fluffette1);
fluffy.Children.Add(fluffette2);

var butch = new Dog();
var butchette1 = new Puppy() { Parent = butch };
var butchette2 = new Puppy() { Parent = butch };

butch.Children.Add(butchette1);
butch.Children.Add(butchette2);

希望这有帮助。