0

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

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

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

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

如果我尽可能忽略该类,我就可以做到这一点,如果我想要一个子表达式,我只拥有List<object>带有List<object>项目的对象,但我宁愿取消这个,而是将一个Expressions 作为子列表(这样更容易对对象进行操作。我知道我可以在对象上使用扩展方法,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;
    }

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

更新:这是交换的代码:

    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;
    }
4

2 回答 2

2

你得到一个的原因StackOverflowException

foreach (var item in (Expression)root)

…内部原因:

((Expression)root).GetEnumerator()

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

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

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

foreach (var item in (Expression)root)

…和:

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

…物业expr名称在哪里。List<object>

于 2012-06-03T22:36:01.023 回答
2

为什么改GetEnumerator()回来了this.GetEnumerator()

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

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

于 2012-06-03T22:37:55.533 回答