2012-02-08 4 views
4

Привет Я пытаюсь создать общий treenode. Вот абстрактный универсальный классInherited Generics Constructor C#

public abstract class TreeNode<T> 
{ 
    protected List<TreeNode<T>> _childNodes = new List<TreeNode<T>>(); 
    protected TreeNode<T> ParentNode; 

    public T ObjectData { get; set; } 

    public TreeNode(TreeNode<T> parent, T data) 
    { 
     ParentNode = parent; 
     ObjectData = data; 
    }  
} 

Он имеет интерфейс компаньона

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

+1

@JonathanVillegas, тогда вы должны принять ответ – phoog

3

Вы должны вызвать конструктор базового класса из вашего FHXTreeNode конструктора:

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

Кроме того, по соглашению, интерфейсы начинаются с заглавной буквы I в .NET, поэтому TreeNodeOperations должен быть ITreeNodeOperations

+0

+1 для IConventionMention –

+0

Спасибо, altho кто-то уже избил вас к нему :) – Nizzy

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

+2

Вы уверены, что хотите ввести параметры типа в методе, а не в тип интерфейса? Приведение этих методов в общий смысл маловероятно. – CodesInChaos

+0

Да, эти интерфейсы были сделаны потому, что я понял, что, например, не все деревья добавляют детей таким же образом. Если бы я был помещен в абстрактный базовый класс, мне пришлось бы перегружать метод addChild, и полученный код был бы хуже, чем сейчас. Поскольку не все деревья добавляют и ищут детей одинаково, я думал об адаптации шаблона стратегии для реализации этих операций дерева. – Nizzy

3

Прежде всего, public и abstract являются недопустимыми ключевыми словами в объявлениях интерфейсов. Ваш интерфейс должен выглядеть следующим образом:

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) { }