汎用 IEnumerator および IComparable の実装に関する問題
-
27-09-2019 - |
質問
私は AVL ツリーに取り組んでいます。ツリー自体は機能しているように見えますが、ツリーの値を処理するにはイテレータが必要です。そこで、IEnumerator インターフェイスを実装してみました。残念ながら、IEnumerator と IComparable を実装するとコンパイル時にエラーが発生します。最初にコード、その下にエラーがあります。
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);
}
}
VS2008 によって表示されるエラー:エラー 1 型 'T' は、ジェネリック型またはメソッド 'Opdr2_AvlTreeTest_Final.AvlTreeNode' の型パラメーター 'T' として使用できません。ボックス化変換や、'T' から 'System.IComparable' への型パラメーター変換はありません。
このエラーは次の行に表示されます。
//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
今のところ、ツリーとノードのロジックは含めていません。この問題を解決する必要があると思う人はいますが、そう言ってください。
THX!
解決
あなたはこの
にそれを変更してみてくださいでした class AvlTreePreOrderEnumerator<T> : IEnumerator<T> where T :IComparable
他のヒント
ノードクラスを次のように宣言したと思われます。
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;}
}
これを試してください (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;}
}
あなたも変える必要があります current
これにフィールドを追加します:
private AvlTreeNode<T> current = new AvlTreeNode<T>();
あなたはエラー(Opdr2_AvlTreeTest_Final.AvlTreeNode
)を引き起こす実際のコードを投稿していない、まだ、私は強く問題があると思われる一方で、あなたがIComparable<T>
を実装するために制約されないの型パラメータでジェネリックメソッド/タイプでこのクラスを使用していることです。
あなたは簡単な例で同様のエラーを再現することができます:
// 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.
}
としては、すでに指摘し、あなたはすべてのコードが含まれていないが、あなただけのIComparableを