.net编译器是否知道从以下代码生成尾递归?
(意思是它知道不应该进行回溯,因为&&
?)
public bool DeleteLocation(Guid locationId)
{
return ((_mLocationDal.Save(locationRes) != null) &&
locationRes.ChildrenIds.Aggregate(true,
(succeededSoFar, next) => succeededSoFar &&
DeleteLocation(next)));
}
答案 0 :(得分:5)
The C# compiler doesn't emit tail calls at all AFAIK。 The JIT of the CLR may discover and apply tail calls however.
答案 1 :(得分:2)
即使C#编译器支持尾递归优化(它没有)它也不会在你的程序中检测到它,因为DeleteLocation
不会直接调用自身。它使用调用DeleteLocation
的仿函数,但这不足以优化递归尾调用。
在旁注中,All
为您的Aggregate
提供了一个更紧凑的替代品:
public bool DeleteLocation(Guid locationId) {
return (_mLocationDal.Save(locationRes) != null) &&
locationRes.ChildrenIds.All(next => DeleteLocation(next));
}
答案 2 :(得分:1)
布尔表达式被懒惰地评估;例如在A && B
中,如果B
为false,则永远不会评估A
。这就是为什么if (thing != null && thing.DoSomething())
这样的事情是安全的。
答案 3 :(得分:1)
C#编译器根本不支持尾递归,如果用“tail”表示调用带有CIL .tail
前缀的方法,它不会在堆栈上留下一个帧。