2012-02-08 156 views
4

嗨我試圖做一個通用treenode。這裏是抽象的泛型類繼承的泛型構造函數C#

​​3210

它有一個同伴接口

interface TreeNodeOperations<T> 
{ 
    //Adds child to tree node 
    public abstract void AddChild<T>(T child); 
    //Performs N-Tree search 
    public abstract TreeNode<T> SeachChild<T>(T child); 
} 

我想要做的就是從這兩繼承:

public class FHXTreeNode<T>: TreeNode<T>, TreeNodeOperations<T> where T : ParserObject 
{ 
    public FHXTreeNode(FHXTreeNode<T> parent, T data) ---> # **ERROR** # 
    { 
     ParentNode = parent; 
     ObjectData = data; 
    } 

    //Adds child to tree node 
    public override FHXTreeNode<T> AddChild<ParserObject>(T childData) 
    { 
     FHXTreeNode<T> child = new FHXTreeNode<T>(this, childData); 

     //_childNodes.Add(child);   

     return child; 
    } 

} 

的錯誤是: 'Parser.Objects.TreeNode'不包含帶0參數的構造函數

幫助Pls!

回答

9

您需要將調用添加到基類的構造函數。

然後,您不需要在FHXTreeNode的構造函數中設置屬性,因爲它是在基類的構造函數中處理的。你的新的構造應該是這樣的:

public FHXTreeNode(FHXTreeNode<T> parent, T data) : base(parent, data) 
{ 
} 
+0

非常感謝。這是一個很大的幫助!然後 – Nizzy 2012-02-08 15:40:13

+1

@JonathanVillegas你應該接受的答案 – phoog 2012-02-10 00:55:51

3

你必須從你的FHXTreeNode構造函數中調用基類構造函數:

public FHXTreeNode(FHXTreeNode<T> parent, T data) 
    : base(parent, data) 
{ 
    ParentNode = parent; 
    ObjectData = data; 
} 

另外,按照慣例,接口以大寫我在.NET開始,所以TreeNodeOperations應該是ITreeNodeOperations

+0

+1 IConventionMention – 2012-02-08 15:20:15

+0

感謝,本書雖然已經有人打你吧:) – Nizzy 2012-02-08 15:39:45

5

您需要調用基類的構造函數。如果您省略了:base(...)調用,則會調用基類的無參數構造函數。由於你的基類沒有這樣的構造函數,你會得到一個錯誤。

public FHXTreeNode(FHXTreeNode<T> parent, T data) 
    :base(parent, data) 
{ 
} 

調用參數基類的構造使得該領域的初始化過於陳舊,因爲他們已經得到了基類分配。

在C#中,您不能繼承構造函數。您在派生類中創建了一個新的構造函數,它恰好與基類構造函數具有相同的簽名。


你的界面太破了:在一個接口不能聲明方法爲public abstract。接口方法總是隱式公開的,從來沒有實現。所以這些修飾符會是多餘的,而且是非法的。


接下來你不能用override接口方法。您只能覆蓋基類中的virtual/abstract方法。當你有一個方法匹配接口中的某個方法時,實現了這個接口方法。


另一個錯誤是,你重複使用類型參數的接口方法:void AddChild<T>(T child);是錯誤的。此語法用於在方法中引入類型參數。但是你想使用來自包含類型的類型參數。所以你應該寫AddChild(T child);


也有一些風格問題:接口的名稱應與I前綴。如有可能,我會盡量避免protected字段。

+0

感謝您的輸入,其實我想要做的是在方法引入類型參數,所以我應該取出是接口名稱中的。我非常感謝你的建議。 – Nizzy 2012-02-08 15:39:26

+2

你確定要在方法中引入類型參數,而不是在接口類型中?使這些方法通用是沒有意義的。 – CodesInChaos 2012-02-08 15:42:24

+0

是的,因爲我意識到例如,並非所有的樹都以相同的方式添加子項,所以製作了這些接口。如果我將它放在抽象基類中,我將不得不重載addChild方法,並且結果代碼會比現在更糟糕。由於不是所有的樹都以相同的方式添加和搜索子項,我正在考慮調整策略模式來實現這些樹操作。 – Nizzy 2012-02-08 16:17:34

3

首先,publicabstract在接口聲明中不是有效的關鍵字。你的界面應該是這樣的:

interface TreeNodeOperations<T> 
{ 
    //Adds child to tree node 
    void AddChild(T child); 
    //Performs N-Tree search 
    TreeNode<T> SeachChild(T child); 
} 

要回答你的問題,因爲TreeNode沒有定義參數的構造函數,像這樣:

public TreeNode() { } 

...然後FHXTreeNode的實例不能無需調用創建它的基礎構造如下:

public FHXTreeNode(FHXTreeNode<T> parent, T data) : base(parent, data) { }