Problèmes avec la mise en œuvre IEnumerator et générique IComparable
-
27-09-2019 - |
Question
Je travaille sur un arbre AVL. L'arbre lui-même semble fonctionner mais je besoin d'un itérateur de marcher à travers les valeurs de l'arbre. J'ai donc essayé de mettre en œuvre le interace IEnumerator. Malheureusement, je reçois une erreur de compilation et la mise en œuvre IEnumerator IComparable. D'abord le code et que l'erreur ci-dessous.
class AvlTreePreOrderEnumerator<T> : IEnumerator<T> where T :IComparable<T>
{
private AvlTreeNode<T> current = default(T);
private AvlTreeNode<T> tree = null;
private Queue<AvlTreeNode<T>> traverseQueue = null;
public AvlTreePreOrderEnumerator(AvlTreeNode<T> tree)
{
this.tree = tree;
//Build queue
traverseQueue = new Queue<AvlTreeNode<T>>();
visitNode(this.tree.Root);
}
private void visitNode(AvlTreeNode<T> node)
{
if (node == null)
return;
else
{
traverseQueue.Enqueue(node);
visitNode(node.LeftChild);
visitNode(node.RightChild);
}
}
public T Current
{
get { return current.Value; }
}
object IEnumerator.Current
{
get { return Current; }
}
public void Dispose()
{
current = null;
tree = null;
}
public void Reset()
{
current = null;
}
public bool MoveNext()
{
if (traverseQueue.Count > 0)
current = traverseQueue.Dequeue();
else
current = null;
return (current != null);
}
}
L'erreur donnée par VS2008: Erreur 1 Le type « T » ne peut pas être utilisé comme paramètre de type « T » dans le type générique ou méthode «Opdr2_AvlTreeTest_Final.AvlTreeNode. Il n'y a pas de conversion de boxe ou de type paramètre conversion de 'T' à 'System.IComparable'.
Cette erreur est donnée sur les lignes suivantes:
//members
private AvlTreeNode<T> current = default(T); //current highlighted
private AvlTreeNode<T> tree = null; //tree highlighted
private Queue<AvlTreeNode<T>> traverseQueue = null; //traverseQueue highlighted
//Constructor
public AvlTreePreOrderEnumerator(AvlTreeNode<T> tree) // AvlTreePreOrderEnumerator highlighted
//Method
private void visitNode(AvlTreeNode<T> node) //visitNode highlighted
Pour l'instant je n'ai pas compris la logique de l'arbre et le noeud. Je pense que tout le monde il est nécessaire de résoudre ce problème, dites donc!
Thx!
La solution
Pourriez-vous essayez de le changer à cette
class AvlTreePreOrderEnumerator<T> : IEnumerator<T> where T :IComparable
Autres conseils
Je vous soupçonne déclaré votre classe de noeud comme ceci:
public class AvlTreeNode<T> where T : IComparable<AvlTreeNode<T>> {
public AvlTreeNode<T> Root;
public AvlTreeNode<T> LeftChild {get;set;}
public AvlTreeNode<T> RightChild {get;set;}
public T Value { get; set;}
}
Essayez ceci (modifié le type de paramètre IComparable):
public class AvlTreeNode<T> where T : IComparable<T> {
public AvlTreeNode<T> Root;
public AvlTreeNode<T> LeftChild {get;set;}
public AvlTreeNode<T> RightChild {get;set;}
public T Value { get; set;}
}
Vous devez également modifier votre champ current
à ceci:
private AvlTreeNode<T> current = new AvlTreeNode<T>();
Alors que vous n'avez pas affiché le code réel provoquant l'erreur (Opdr2_AvlTreeTest_Final.AvlTreeNode
) encore, je soupçonne fortement le problème est que vous utilisez cette classe dans une méthode / type générique avec un paramètre de type qui n'est pas contraint de mettre en œuvre IComparable<T>
.
Vous pouvez reproduire une erreur semblable avec un exemple simple:
// no problem here at definition site:
void IsLarger<T>(T a, T b) where T : IComparable<T> {
return a.CompareTo(b) > 0;
}
void Test<T>(T arg) { // note: T is not necessarily IComparable<T>
Console.WriteLine(IsLarger(arg, arg)); // The compiler shouldn't allow this.
}
Comme l'a souligné déjà, vous n'avez pas inclus tout le code, mais vous ne contraint T à IComparable