2009-08-20 6 views
2

J'ai créé un BinaryTreeNode<T> et puis en créant Add(T data) méthode pour BinaryTree<T> classe.Comparaison en C#: l'opérateur « < » ne peut pas être appliqué aux opérandes de type « T » et classe « T »

Lorsque je tente de comparer les valeurs de compilateur objets dit:

opérateur « < » ne peut pas être appliqué aux opérandes de type « T » et « T ».

Exemple:

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

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

J'utilise VS08 Express Edition.

+0

Avez-vous fait une classe nommée "T"? – cakeforcerberus

Répondre

8

Vous devez ajouter une contrainte telle que T doit mettre en œuvre IComparable<T> et utiliser ensuite que:

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) 
     ... 

Une alternative est de passer dans un IComparer<T> et l'utiliser:

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) 

C'est le plus proche vous pouvez obtenir la garantie d'un opérateur "<" - les opérateurs surchargés sont statiques, et il n'y a aucun moyen de contraindre un argument de type à l'exiger.

+0

Impressionnant. J'aurais dû demander avant 3h :-). Souhaitez-vous s'il vous plaît ajouter sur la façon d'implémenter IComparable pour Ts qui ne l'implémente pas. –

+0

Si T lui-même n'implémente pas IComparable 'alors vous voudrez probablement utiliser l'approche' IComparer 'à la place - c'est assez simple à implémenter, vous comparez simplement les valeurs données et renvoyez un nombre négatif, un nombre positif ou 0 selon sur cette comparaison. –

1

Regardez en utilisant Generic Constraints pour affiner les types que T peut être. De cette façon, vous pouvez vous assurer qu'ils peuvent être comparés en utilisant votre opérateur.

Pour l'instant T pourrait être tout objet. Par exemple, si vous aviez un objet Car, comment le compilateur pourrait-il savoir que dire qu'une voiture est «inférieure à» ou «supérieure à» une autre? C'est pourquoi vous avez besoin de contraintes.

+0

Merci. Vous avez supprimé les doutes sur les raisons pour lesquelles ils ne peuvent pas être comparés. (+ 1) –

1

Le type (int, chaîne, char [], MyClass, YourClass, etc.) de Value ne prend pas en charge l'opération '<'. Cela est normal pour la plupart des types de numéros non intrinsèques, soit int, long, décimales, etc.

T doit mettre en œuvre la classe IComparable de sorte qu'il peut être comparé à un autre objet de type T.

Ainsi, vous déclaration de fonction doit appliquer une contrainte sur T:

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

et vous devez vous assurer que les T est, il faut mettre en œuvre IComparable.

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

Dans votre fonction add, puis appelez-vous

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