泛型、抽象类、构造函数

3

我有一个抽象基类

class AbstractClass 
{
    Col<AbstractClass> parent

    public AbstractClass()
    {
        //do stuff
    }
}

我有两种实现方法

class A : AbstractClass 
{ 
    Col<A> parent

    public A(Col<A> parent)
        :base(parent)
    {
        this.parent = parent;
    }  

}

class B : AbstractClass 
{ 
    Col<B> parent

    public B(Col<B> parent)
        :base(parent)
    {
        this.parent = parent;
    }
}

我有一个集合

class Col<T> : IList<T> where T : AbstractClass

这段代码将被用于另一个类中,作为Col<A>Col<B>,我们称之为C

class C
{
    List<A> a = new List<A>()
    List<B> b = new List<B>()
}

这一切都可以实现,但是我希望类型AB能够知道它们的父集合。我认为在AbstractClass、A和B中使用以下构造函数应该没问题,但似乎泛型约束只能用于类而不是方法。基本上,我想要以下构造函数:

public AbstractClass(Col<T> where T : AbstractClass)
public A(Col<A>)
public B(Col<B>)

A、B的实例需要知道它们所在的集合,但我无法从派生类中调用基础构造函数,因为它们是不同类型。

求助!

4个回答

4

当我想要进行类似以下操作时,我经常使用与C++ 奇异递归模板模式相关的模式:

abstract class AbstractClass<TDerivedClass>
    where TDerivedClass : AbstractClass<TDerivedClass>
{
    Col<TDerivedClass> parent;

    public AbstractClass(Col<TDerivedClass> parent)
    {
        // do stuff
        this.parent = parent;
    }
}

class A : AbstractClass<A>
{ 
    public A(Col<A> parent)
        :base(parent) {}
}

class B : AbstractClass<B>
{ 
    public A(Col<B> parent)
        :base(parent) {}
}

1

使用自定义的Collection<T>类型,而不是List<T>。它们基本上提供相同的功能(Collection<T>在内部使用List<T>),并且专门用于此目的。

然后,您可以重写InsertItem来设置添加到集合中的任何项的父项。

public class MyCollection<T> : System.Collections.ObjectModel.Collection<T>
{
    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        item.Parent = this;
    }
}

@Matt:出于简洁的目的,我没有包含构造函数。当然,你需要添加链接到基本构造函数的构造函数。 - Noldorin
我已经编辑了我的问题以更好地解释我的问题。我认为我们在这方面走在了正确的轨道上。 - Matt Jacobsen
不,这样行不通。我仍然需要在抽象类中使用类似于protected Col<AbstractClass> parent的东西,以被A中的protected Col<A> parent和B中的protected Col<B> parent所覆盖。 - Matt Jacobsen
1
@Matt:你可以使用 new 关键字在基类中隐藏 Col<AbstractClass> 属性,或者只是保持原样并进行强制转换。但是你无法覆盖它,这是你必须接受的事实。 - Noldorin
1
另外,请注意您可以在方法/构造函数上设置通用类型约束。例如:public void Foo<T>(T bar) where T : AbstractClass { ... } - Noldorin
显示剩余2条评论

1
我希望类型A和B能够了解它们所属的父集合。
你可能会对这篇文章感兴趣。我写它时考虑了XML序列化,但它也可以在更一般的情况下使用。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接