2013-04-16 34 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

相關問題