Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inherited Generics Constructor C#

Hi I'm trying to make a generic treenode. Here is the abstract generic class

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;
    }    
}

It has a companion interface

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

What I'm trying to do is inherit from both of these:

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;
    }

}

The error is: 'Parser.Objects.TreeNode' does not contain a constructor that takes 0 arguments

Help Pls!

like image 555
Ziony Avatar asked Feb 08 '12 15:02

Ziony


2 Answers

You need to add a call to the base class' constructor.

And, subsequently, you don't need to set the properties inside of FHXTreeNode's constructor since it's handled in the base class' constructor. Your new constructor should look like this:

public FHXTreeNode(FHXTreeNode<T> parent, T data) : base(parent, data)
{
}
like image 120
Justin Niessner Avatar answered Oct 07 '22 15:10

Justin Niessner


You need to call the constructor of the base class. If you omit the :base(...) call, the parameterless constructor of the base class gets called. Since your base class doesn't have such a constructor, you get an error.

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

Calling the parameterized base class constructor makes the field initializations obsolete too, since they already get assigned to in the base class.

In C# you can't inherit constructors. You create a new constructor in the derived class that happens to have the same signature as the base class constructor.


Your interface is broken too: You can't declare methods as public abstract in an interface. Interface methods are always implicitly public, and never have an implementation. So those modifiers would be redundant, and are illegal.


Next you can't override interface methods. You can only override virtual/abstract methods from a base class. When you have a method which matches a method in an interface, in implements that interface method.


Yet another mistake is that you reuse the type parameter on the interface methods: void AddChild<T>(T child); is wrong. This syntax is for introducing type parameters on a method. But you want to use the type parameter from the containing type. So you should write AddChild(T child);.


There are also a few stylistic issues: Interface names should be prefixed with I. And I'd avoid protected fields where possible.

like image 21
CodesInChaos Avatar answered Oct 07 '22 15:10

CodesInChaos