Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic tree of generic node C#

Tags:

c#

.net

generics

I'm trying to create a generic tree class of generic node objects.

using System;
using System.Collections;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        Tree<Node<int>> tree = new Tree<Node<int>>();
    }
}

public class Tree<T> : IEnumerable<T>
    where T : IComparable<T>
{
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

public class Node<TNode> : IComparable<TNode>
    where TNode : IComparable<TNode>
{
    TNode Value;
    public int CompareTo(TNode other)
    {
        return Value.CompareTo(other);
    }
}

But in the main method I'm receiving compilation error:

The type 'BinaryTree.Node<int>' cannot be used as type parameter 'T' in the generic type or method 'Tree<T>'. There is no implicit reference conversion from 'BinaryTree.Node<int>' to 'System.IComparable<BinaryTree.Node<int>>'.

Can someone help me understand what is the problem?

like image 723
Ttech Avatar asked Mar 19 '26 06:03

Ttech


2 Answers

The problem is in your Node<> class - you've said that a Node is comparable to the type of value inside it. Instead, you should say it's comparable to another node with the same value:

public class Node<TNode> : IComparable<Node<TNode>>
    where TNode : IComparable<TNode>
{
    TNode Value;
    public int CompareTo(Node<TNode> other)
    {
        return Value.CompareTo(other.Value);
    }
}

At that point, it's find to create a Tree<Node<int>>.

But it might be better to actually create a Tree<int>, and make Tree<T> use Node<T> internally instead. That's likely to be easier to use. After all, every tree will have nodes. It's hard to say for sure with relatively little code, but I suspect that's actually what you want to do.

like image 65
Jon Skeet Avatar answered Mar 21 '26 20:03

Jon Skeet


I guess you got confused by your naming standard, just as I were.

This declaration has a problem:

public class Node<TNode> : IComparable<TNode>
    where TNode : IComparable<TNode>

Let's rewrite it by renaming the generic parameter:

public class Node<T> : IComparable<T>
    where TNode : IComparable<T>

Here you can see that you declared it as being able to be compared against the values it stores, not against other nodes.

Since the tree type requires its T to be able to compare against values of the same type, you need the nodes to be able to compare against other nodes, like this:

                                   changed
                                   v-----v
public class Node<T> : IComparable<Node<T>>
    where TNode : IComparable<TNode>
like image 41
Lasse V. Karlsen Avatar answered Mar 21 '26 19:03

Lasse V. Karlsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!