【问题标题】:Problems with implementing generic IEnumerator and IComparable实现通用 IEnumerator 和 IComparable 的问题
【发布时间】:2010-05-15 11:18:32
【问题描述】:

我正在研究 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  

目前我还没有包含树和节点逻辑。我有人认为有必要解决这个问题,就这么说吧!

谢谢!

【问题讨论】:

  • 据我所知,您还没有发布 C# 编译器抱怨的代码。
  • 添加了 C# 抱怨的代码:)

标签: c# generics interface icomparable ienumerator


【解决方案1】:

你能不能改成这样

class AvlTreePreOrderEnumerator&lt;T&gt; : IEnumerator&lt;T&gt; where T :IComparable

【讨论】:

  • 这是解决方案,在我删除了 ICmarable 后面的 之后,编译器向我显示了另一个错误。这个错误让我意识到我犯了一个愚蠢的错误。来自三个成员: private AvlTreeNode current = default(T);私有 AvlTreeNode 树 = null;私有队列> traverseQueue = null;第二个成员不应该是 AvlTreeNode 而是 AvlTree 。修改后一切正常:)谢谢大家的帮助!
【解决方案2】:

我怀疑你声明你的节点类是这样的:

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>();

【讨论】:

    【解决方案3】:

    虽然您尚未发布导致错误的实际代码 (Opdr2_AvlTreeTest_Final.AvlTreeNode),但我强烈怀疑问题在于您在泛型方法/类型中使用此类,其类型参数不受限制实现 @ 987654322@.

    您可以通过一个简单的示例重现类似的错误:

    // 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.
    }
    

    【讨论】:

      【解决方案4】:

      正如已经指出的,您没有包含所有代码,但您仅将 T 限制为 IComparable,而您列出的错误是它希望 T 实现 IComparable(即非泛型形式IComparable)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多