tags:

views:

134

answers:

3

I have created a BinaryTreeNode<T> class and then creating Add(T data) method for BinaryTree<T> class.

When I try to compare Values of objects compiler says :

operator '<' cannot be applied to operands of type 'T' and 'T'.

Example:

  public void AddNode(T data) {
        BinaryTreeNode<T> node = new BinaryTreeNode<T>(data);
        BinaryTreeNode<T> temp = root;

        if (temp.Value < node.Value) // **PROBLEM HERE**
        ...

I'm C# noob and using VS08 Express Edition. Please help.

+1  A: 

Look into using Generic Constraints to narrow down the types that T can be. That way you can ensure that they can be compared using your operator.

At the moment T could be any object. For instance, if you had a Car object, how would the compiler know what to make of saying one Car is "less than" or "greater than" another? That is why you need constraints.

Dan Diplo
Thanks.You removed doubts about why they can't be compared.(+1)
TheMachineCharmer
+8  A: 

You should add a constraint such that T must implement IComparable<T> and then use that:

public class BinaryTree<T> where T : IComparable<T>
{
    public void AddNode(T data)
    {
        BinaryTreeNode<T> node = new BinaryTreeNode<T>(data);
        BinaryTreeNode<T> temp = root;

        if (temp.Value.CompareTo(node.Value) < 0)
        ...

An alternative is to pass in an IComparer<T> and use that:

public class BinaryTree<T> where T : IComparable<T>
{
    private readonly IComparer<T> comparer;

    public BinaryTree(IComparer<T> comparer)
    {
        this.comparer = comparer;
        ...
    }

    public void AddNode(T data)
    {
        BinaryTreeNode<T> node = new BinaryTreeNode<T>(data);
        BinaryTreeNode<T> temp = root;

        if (comparer.Compare(temp.Value, node.Value) < 0)

This is the closest you can get to guaranteeing a "<" operator - overloaded operators are static, and there's no way of constraining a type argument to require it.

Jon Skeet
Awesome.I should have asked before 3hrs :-). Would you please add on how to implement IComparable<T> for Ts that dont implement it.
TheMachineCharmer
If T itself doesn't implement `IComparable<T>` then you probably want to use the `IComparer<T>` approach instead - it's pretty simple to implement, you just compare the given values and return a negative number, a positive number or 0 depending on that comparison.
Jon Skeet
+1  A: 

The type (int, string, char[], MyClass, YourClass, etc) of Value doesn't support the '<' operation. That is normal for most non-intrinsic number types, i.e. int, long, decimal, etc.

T needs to implement the IComparable class so it can be compared with other object of type T.

So, you function declaration must enforce a constraint on T:

public class BinaryTree<T> where T : IComparable<T>
{
    public void AddNode(T data)

and you must make sure that whatever T is, it must implement IComparable.

public class MyData : IComparable<MyData>
{
    public int CompareTo(MyData other)
    {
         // return -1 if 'this' is smaller than other, 0 if equals, 1 otherwise
    }
}

In your add function, you then call

if( temp.Value.CompareTo(node.Value) < 0 )
ADB