2012-01-25 23 views
6

Aquí está mi código:Genéricos dolorosas, operador '> =' no se pueden aplicar a operandos de tipo 'T' y 'T'

class BinaryTree<T> 
{ 
    private node<T> Head; 
    public class node<T> 
    { 
    public T Data; 
    public node<T> right; 
    public node<T> left; 
    public node<T> parent; 
    ... 
    } 
    ... 
    private void insert(ref T data, node<T> parent, ref node<T> currentChild) 
    { 
    ... 
     { 
      if (currentChild.Data >= data) insert(ref data, currentChild, ref currentChild.right); 
      else insert(ref data, currentChild, ref currentChild.left); 
     } 
    } 
} 

encima en el punto if (currentChild.Data >= data) estoy consiguiendo error:

operador '> =' no se puede aplicar a operandos de tipo 'T' y 'T'

¿Qué hago para resolver el error?

Respuesta

8

Las soluciones clásicas a este problema son (1) para hacer TIComparable<T>, o (2) el uso de un IComparer<T> o una functor para tu clase.

(1)

class BinaryTree<T> where T : Comparable<T> ... 

(2)

class BinaryTree<T> { 
    private node<T> Head; 
    private readonly IComparer<T> comparer; 
    public BinaryTree(IComparer<T> comparer) { 
     this.comparer = comparer; 
    } 
    //... 
} 
+0

¿Puedes explicar cómo funciona eso donde T: IComparable le dice al compilador que T implementa IComparable? –

+0

@ Mr.Anubis Esa es una condición en el tipo genérico T: le dice al compilador que 'BinaryTree ' * no puede * crearse, a menos que 'T' implemente' IComparable '. – dasblinkenlight

+0

Entonces, ¿qué sucede si instancia un T con los tipos definidos por el usuario que no implementa (hereda) 'IComparable ', rompe aún la política? no? –

1

No sé C#, pero en Java necesitaría tener una instancia de una clase Comparator genérica, parametrizada con los tipos que desea comparar. Esta clase genérica proporcionó una función compareTo() que se implementaría de una manera que permita la comparación de los dos tipos.

10

Es necesario especificar que T implementa IComparable por lo que se puede comparar:

class BinaryTree<T> where T : IComparable<T> 
{ 
    ... 
    public class node<T> where T : IComparable<T> ... 
    ... 
    if (currentChild.Data.CompareTo(data) >= 0) ... 
    ... 
} 
+0

Pero no quiero usar esa notación 'currentChild.Data.CompareTo (data)> = 0', ¿Algún otro método? –

1

T debe ser un tipo que implementa IComparable y luego usar su compareTo a método en lugar de> =. La sobrecarga del operador es otra opción si aún desea admitir> =.

0

Supongo que los datos son del tipo Object y por lo tanto no permiten automáticamente una operación> =.
es necesario agregar una restricción para T de modo que sea IComparable

class BinaryTree<T> where T : IComparable 
1

Mientras que algunas personas sugieren usar IComparable, se recomienda usar un IComparer<T> lugar, que debe ser almacenado en un campo de su árbol. Uno de los constructores de su árbol debe aceptar un IComparer<T>, que debe almacenarse en su campo. El otro probablemente debería establecer el campo IComparer<T> en Comparer<T>.InvariantDefault(). Los consumidores de tu árbol podrán elegir cómo se ordenarán las cosas dentro del árbol. Tenga en cuenta que si se suministra un IComparer<T> cuando se construye una clase, no existe un motivo real para que T deba implementar IComparable<T>. Podría ser útil aplicar un requisito de tiempo de compilación que T implemente IComparer<T> al construir un árbol sin especificar un método de comparación, pero no hay forma de hacerlo sin requerir una sintaxis un tanto incómoda como treeInstance = factoryClass.Create<myType>() que crearía una instancia de treeClass<myType>.

Cuestiones relacionadas