Problemas com a implementação do ienumerador genérico e iComparable
-
27-09-2019 - |
Pergunta
Estou trabalhando em uma árvore AVL. A própria árvore parece estar funcionando, mas preciso de um iterador para percorrer os valores da árvore. Portanto, tentei implementar a interação do iEnumerator. Infelizmente, recebo um erro de tempo de compilação implementando o iEnumerator e o ICOMPARABLE. Primeiro o código e abaixo do erro.
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);
}
}
O erro dado pelo vs2008: erro 1 O tipo 't' não pode ser usado como parâmetro de tipo 't' no tipo genérico ou método 'opdr2_avltreetretest_final.avltreenode'. Não há conversão de boxe ou conversão de parâmetros de tipo de 'T' para 'System.icomparable'.
Este erro é apresentado nas seguintes linhas:
//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
Por enquanto, não incluí a lógica da árvore e do nó. Alguém acha que é necessário resolver esse problema, apenas diga!
THX!
Solução
Você poderia tentar mudar para isso
class AvlTreePreOrderEnumerator<T> : IEnumerator<T> where T :IComparable
Outras dicas
Eu suspeito que você declarou sua classe de nó como este:
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;}
}
Tente isso (tipo de parâmetro IComparável alterado):
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;}
}
Você também tem que mudar seu current
Campo para isso:
private AvlTreeNode<T> current = new AvlTreeNode<T>();
Enquanto você não publicou o código real causando o erro (Opdr2_AvlTreeTest_Final.AvlTreeNode
), no entanto, suspeito fortemente que o problema é que você esteja usando esta classe em um método/tipo genérico com um parâmetro de tipo que não está restrito a implementar IComparable<T>
.
Você pode reproduzir um erro semelhante com um exemplo simples:
// 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.
}
Como já foi apontado, você ainda não incluiu todo o códigou003CT> , enquanto o erro que você listou é que ele deseja implementar o ICOMPARABLE (ou seja, a forma não genérica de ICOMPARABLE)