递归迭代器

本文关键字:迭代器 递归 | 更新日期: 2023-09-27 18:36:19

我在制作可以遍历以下类型的数据结构的迭代器时遇到了一些麻烦。

我有一个名为 Expression 的类,它有一个数据成员 a List<object>

此列表可以有任意数量的子对象,其中一些子对象可能是其他 Expression 对象。

我想遍历这个结构,并打印出每个非列表对象(但我当然想打印出列表的元素),但在输入列表之前,我想返回"开始嵌套",在我刚刚退出列表后,我想返回"结束嵌套"。

如果我尽可能忽略类,并且如果我想要一个子表达式,我就可以

做到这一点,并且如果我想要一个子表达式,我只需要List<object>带有List<object>项目的对象,但我宁愿取消它,而是有一个Expression s作为子列表(这将使对对象进行操作更容易。我知道我可以在List<object>上使用扩展方法,但这是不合适的(谁想要他们的列表中没有参数的Evaluate方法?

我用来生成原始迭代器(有效)的代码是:

    public IEnumerator GetEnumerator(){
        return theIterator(expr).GetEnumerator();
    }
    private IEnumerable theIterator(object root) {
        if ((root is List<object>)){
            yield return " begin nest ";
            foreach (var item in (List<object>)root){
                foreach (var item2 in theIterator(item)){
                    yield return item2;
                }
            }
            yield return " end nest ";
        }
        else
            yield return root;
    }

表达式的类型交换List<object>不起作用,并导致堆栈溢出错误。迭代器应该如何实现?

更新:这是交换的代码:

    public IEnumerator GetEnumerator() {
        return this.GetEnumerator();
    }
    private IEnumerable theIterator(object root) {
        if ((root is Expression)) {
            yield return " begin nest ";
            foreach (var item in (Expression)root) {
                foreach (var item2 in theIterator(item))
                    yield return item2;
            }
            yield return " end nest ";
        }
        else
            yield return root;
    }

递归迭代器

你得到StackOverflowException的原因是

foreach (var item in (Expression)root)

。内部原因:

((Expression)root).GetEnumerator()

。要调用 – 这是 CLR 枚举在 foreach 循环的每次迭代期间必须分配给 item 变量的对象的方式。

在您的情况下,GetEnumerator()调用将导致theIterator再次执行相同的root,从而进入无限递归。

要解决您的问题,您需要替换:

foreach (var item in (Expression)root)

。跟:

foreach (var item in ((Expression)root).expr)

。其中exprList<object>属性的名称。

你为什么把GetEnumerator()改成返回this.GetEnumerator()

在我看来,这就是您的堆栈溢出的来源。

尝试让它返回theIterator(this).GetEnumerator()