是,,尾部递归就讲到这里

本文关键字:这里 递归 尾部 | 更新日期: 2023-09-27 18:18:03

.net编译器知道从下面的代码产生尾部递归吗?(这意味着它知道不应该进行回溯,因为&& ?)

public bool DeleteLocation(Guid locationId)
{
    return ((_mLocationDal.Save(locationRes) != null) && 
             locationRes.ChildrenIds.Aggregate(true, 
                        (succeededSoFar, next) => succeededSoFar && 
                                                  DeleteLocation(next)));
}

是,,尾部递归就讲到这里

c#编译器根本不发出尾部调用。然而,CLR的JIT可能会发现并应用尾部调用。

即使c#编译器支持尾部递归优化(它不支持),它也不会在您的程序中检测到它,因为DeleteLocation不直接调用自己。它使用的函子调用DeleteLocation,但这不足以优化递归尾部调用。

另外,在您的情况下,AllAggregate提供了更紧凑的替代品:

public bool DeleteLocation(Guid locationId) {
        return (_mLocationDal.Save(locationRes) != null) && 
            locationRes.ChildrenIds.All(next => DeleteLocation(next));
    }

布尔表达式延迟求值;例如,在A && B中,如果A为假,则永远不会计算B。这就是为什么做if (thing != null && thing.DoSomething())这样的事情是安全的。

c#编译器根本不支持尾部递归,如果你说的"尾部"是指调用带有CIL的.tail前缀的方法,它不会在堆栈上留下一个帧。