2012-01-25 14 views
6

Ecco il mio codice:Generics dolorose, Operatore '> =' non possono essere applicate a operandi di tipo 'T' e '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); 
     } 
    } 
} 

Sopra al punto if (currentChild.Data >= data) sto ottenendo errore:

Operatore '> =' non può essere applicato a operandi di tipo 'T' e 'T'

Cosa devo fare per risolvere l'errore?

risposta

8

Le soluzioni classiche a questo problema sono (1) per fare TIComparable<T>, o (2) di utilizzare un IComparer<T> o un funtore della tua classe.

(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

puoi spiegare come funziona T: IComparable indica al compilatore che T implementa IComparable? –

+0

@ Mr.Anubis Questa è una condizione del tipo generico T: dice al compilatore che 'BinaryTree ' * non può * essere creato, a meno che 'T' implementi' IComparable '. – dasblinkenlight

+0

Quindi, se istanzio T con tipi definiti dall'utente che non implementa (eredita) 'IComparable ', interrompe ancora la politica? non è vero? –

1

Non so C#, ma in Java è necessario disporre di un'istanza di una classe Comparator generica, parametrizzata con i tipi che si desidera confrontare. Questa classe generica ha fornito una funzione compareTo() che sarebbe stata implementata in un modo che consenta il confronto tra i due tipi.

10

è necessario specificare che T implementa IComparable in modo da poter confrontare:

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

Ma non voglio usare quella notazione 'currentChild.Data.CompareTo (data)> = 0', Qualsiasi altro metodo? –

1

T deve essere un tipo che implementa IComparable e quindi utilizzare la sua compareTo metodo invece di> =. L'overloading dell'operatore è un'altra opzione se vuoi ancora supportare> =.

0

Suppongo che Data sia di tipo Object e pertanto non consenta automaticamente un'operazione> =.
È necessario aggiungere un vincolo per T in modo che sia IComparable

class BinaryTree<T> where T : IComparable 
1

Mentre alcune persone suggeriscono di usare IComparable, vi suggerirei di usare un IComparer<T> invece, che dovrebbe essere memorizzato in un campo del vostro albero. Uno dei costruttori per il tuo albero dovrebbe accettare un IComparer<T>, che dovrebbe essere memorizzato nel tuo campo. L'altro dovrebbe probabilmente impostare il campo IComparer<T> su Comparer<T>.InvariantDefault(). I consumatori del tuo albero saranno quindi in grado di scegliere come verranno ordinate le cose all'interno dell'albero. Si noti che se viene fornito un quando viene creata una classe, non c'è una vera ragione per cui T debba implementare IComparable<T>. Potrebbe essere utile imporre un requisito in fase di compilazione che T implementa IComparer<T> durante la costruzione di un albero senza specificare un metodo di confronto, ma non c'è modo di farlo senza richiedere una sintassi piuttosto scomoda come treeInstance = factoryClass.Create<myType>() che creerebbe un'istanza di treeClass<myType>.

Problemi correlati