今天工作中有这样一个需求:遍历树节点,根据子节点是否全部显示来处理父节点。
写完后测试发现,有时候会出现子节点没有完全遍历的问题,代码如下:
public bool ExcuteRecursive(Func<bool, bool> callback)
{
bool childrenAllShow = true;
for (int i = 0; i < children.Count; i++)
{
childrenAllShow = childrenAllShow && children[i].ExcuteRecursive(callback);
}
return callback(childrenAllShow);
}
假设数据大概是这样的:
由于执行后置,所以顺序应该是:4->2->5->3->1
但事实是:有时候正确,有时候是:4->2->1
为什么少了一个分支呢?
后来检查代码的时候想到,逻辑的&&和||运算内部在执行的时候是有优化的:
&&运算左边的表达式结果为false时,右边的表达式是不执行的;
同样,||运算左边的表达式结果为true,右边的表达式也不执行。
修改之后,测试通过
public bool ExcuteRecursive(Func<bool, bool> callback)
{
bool childrenAllShow = true;
for (int i = 0; i < children.Count; i++)
{
//错误的写法:如果某一次结果为false,与其平级的子分支都不会执行
//childrenAllShow = childrenAllShow && children[i].ExcuteRecursive(callback);
//正确的写法
bool childNeedShow = children[i].ExcuteRecursive(callback);
childrenAllShow = childrenAllShow && childNeedShow;
}
return callback(childrenAllShow);
}