2011-12-17 103 views
1

.net编译器是否知道从下面的代码中产生尾递归? (这意味着它知道没有回溯应作出,因为&&的,?)是否足够用于尾递归?

public bool DeleteLocation(Guid locationId) 
{ 

    return ((_mLocationDal.Save(locationRes) != null) && 
      locationRes.ChildrenIds.Aggregate(true, 
         (succeededSoFar, next) => succeededSoFar && 
                DeleteLocation(next))); 
} 
+0

这可能是一个有趣的问题,但所有的答案到目前为止似乎是一个事实,固定的*编译器*不执行这些操作,而是CLR的JIT编译器。如果这就是你问的问题,你应该考虑编辑这个问题来删除对编译器的错误引用。 – 2011-12-17 11:34:29

回答

1

布尔表达式懒洋洋地评估;例如在A && B中,如果A为假,则从不评估B。这就是为什么像if (thing != null && thing.DoSomething())这样做是安全的。

1

C#编译器根本不支持尾递归,如果用“tail”表示用CIL的.tail前缀调用方法,它不会在栈上留下帧。

2

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

在一个侧面说明,All提供你的情况为Aggregate更紧凑的更换:

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