递归迭代器
本文关键字:迭代器 递归 | 更新日期: 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)
。其中expr
是List<object>
属性的名称。
你为什么把GetEnumerator()
改成返回this.GetEnumerator()
?
在我看来,这就是您的堆栈溢出的来源。
尝试让它返回theIterator(this).GetEnumerator()
?