2013-04-16 40 views
3

所以我想设置一个抽象基类来派生子类。所有的工作都将发生在孩子身上,但我希望孩子们能够互相参考。C#创建一个列表来保存基类的任何派生子项

下面是一些伪代码:

public abstract class BaseClass<T> : SomeOtherClass { 

    public List<BaseClass> listOfChildren; 

    protected T thisChild; 

    public void DoMoreStuff(){ 
     Debug.Log("Doing more stuff"); 
    } 

    protected virtual void DoSomething(int i){ 
     listOfChildren[i].DoMoreStuff(); 
    } 
} 

public class FirstChildClass : BaseClass<FirstChildClass> { 

    FirstChildClass<T>(){ 
     thisChild = this; 
    } 

    public void FirstClassStuff(){ 
     Debug.Log("first class stuff"); 
    } 

} 
public class SecondChildClass : BaseClass<SecondChildClass> { 

    public void SecondClassStuff(){ 
     Debug.Log("second class stuff"); 
    } 
} 

我将如何做一个泛型列表接受任何子类?

我需要与T使用DoMoreStuff()类型转换listOfChildren吗?

就其本身而言,这种设置还有什么内在的错误吗?

回答

4

我想你overcompicate的解决方案。如果你不想在每个节点中存储任何数据 - 尝试解决这个问题,然后没有泛型。我会给你一个天真的直接实现期望的行为作为一个起点。

public abstract class BaseClass { 

    private IList<BaseClass> children = new List<BaseClass>(); 

    public void AddChild(BaseClass child) 
    { 
     this.children.Add(child); 
    } 

    protected virtual void DoMoreStuff(){ 
     Debug.Write("Doing more stuff"); 
    } 

    public void DoSomething(int i){ 
     children[i].DoMoreStuff(); 
    } 
} 

public class FirstChildClass : BaseClass { 

    protected override void DoMoreStuff(){ 
     Debug.Write("first class more stuff"); 
    } 

} 

public class SecondChildClass : BaseClass { 

    protected override void DoMoreStuff(){ 
     Debug.Write("second class more stuff"); 
    } 
} 

现在你可以

var root = new FirstChildClass(); 

root.AddChild(new FirstChildClass()); 
root.AddChild(new SecondChildClass()); 
root.AddChild(new FirstChildClass()); 

root.DoSomething(1); //will print second class more stuff 
root.DoSomething(0); //will print first class more stuff 
+0

进一步,我可以轻松地让每个孩子类Singleton? – user1297102

+0

@ user1297102你真的需要吗? –

+0

它在某些情况下会很有用,难道这会有些困难吗?我想我可以把一个 '受保护的静态T实例'(但这将需要BaseClass 仪式?)在基地,不知道如何设置构造函数if(!实例)instance = this; else“already exists “反对这一点。 – user1297102

3

您需要分开儿童和孩子数据。一个子类只是继承它的父类,以便为数据提供更详细的结构(如AnimalDog)。另一方面,子数据意味着无论数据代表是否彼此相关(例如ReceiptReceiptLineItem)。

通常,两者不重叠。 Receipt类看起来不像ReceiptLineItem类,而ReceiptExternalPurchaseOrder与对方无关,即使它们都从Purchase继承它们的结构。当它们重叠时,你有一个树形结构。 A Product可以由更多的Product组成,每个可以由更多的Product组成。


以下是我已经重写你的代码,假设你正在寻找的第一类继承(类结构):

public abstract class BaseClass : SomeOtherClass { 

    public static List<BaseClass> listOfChildren = new List<BaseClass>(); 

    public void DoMoreStuff(){ 
     Debug.Log("Doing more stuff"); 
    } 

    protected virtual void DoSomething(int i){ 
     listOfChildren[i].DoMoreStuff(); 
    } 
} 

public class FirstChildClass : BaseClass { 

    FirstChildClass(){ 
     // Set some things unique to this class 
    } 

    public void FirstClassStuff(){ 
     Debug.Log("first class stuff"); 
    } 

} 
public class SecondChildClass : BaseClass<SecondChildClass> { 

    public void SecondClassStuff(){ 
     Debug.Log("second class stuff"); 
    } 
} 

然后,您可以访问主目录为BaseClass.listOfChildren。如果你希望所有的孩子把自己自动注册,您可以添加到BaseClass构造:

protected BaseClass() 
{ 
    listOfChildren.Add(this); 
} 
+0

采取进一步行动,我可以很容易地使每个子类一个Singleton? – user1297102

+0

只是出于技术上的好奇,如果我想实现我的低于恒星的设计,那么如何才能使该列表工作? (如果将来我需要混合泛型和类) – user1297102

+1

@ user1297102 - 我不太清楚你的意思。如果你问如何有一个'List ',那么你实际上需要一个'BaseClass'类(或接口),该类可以继承(或实现)BaseClass 。 'BaseClass '的存在并不意味着存在一个非泛型的形式,每个不同的'T'产生一个不同的类,所以如果你只有泛型类型,就没有办法对它们进行“分组”。 – Bobson

相关问题