如何重构短路评估

时间:2013-09-20 06:30:46

标签: delphi

我来自c ++背景,我对这样的声明之一感到困惑

   if TUtils.CheckValue(objData, LChan) and
         (LChan.Int.Value = (aObject as TomDBChan).Int.Value) then
   begin
          //Operation
   end;

可以将其转换为

         LChan.Int.Value = (aObject as TomDBChan).Int.Value ;
          if TUtils.CheckValue(objData, LChan) then
          begin
            //Operation
          end;

还是我应该检查一下LChan.Int.Value是否有一些价值?

2 个答案:

答案 0 :(得分:2)

如果你的目标是阻止任何短路评估,只需确保表达式的组成部分是单独计算的:

b1 := TUtils.CheckValue(objData, LChan);
b2 := (LChan.Int.Value = (aObject as TomDBChan).Int.Value);

if b1 and b2 then
begin
   //Operation
end;

这可确保执行CheckValue()或.Value方法中的任何副作用

答案 1 :(得分:1)

更清楚:你建议的重构是不行的。

语句:“LChan.Int.Value =(aObject as TomDBChan).Int.Value”返回true或false,将它放在if条件之外是没有意义的。

你不能盲目地重构短路评估。那是因为如果左侧是假的,则不评估右侧。这样做会改变你的程序逻辑。

我不能说checkvalues做了什么,但如果它检查空指针怎么办?如果你将它重构为:

b1 := TUtils.CheckValue(objData, LChan);
b2 := (LChan.Int.Value = (aObject as TomDBChan).Int.Value);

事实证明LChan会为null然后你的程序会在b2上引发异常:= ...因为LChan.Int不存在以前不会引发异常的地方。

LChan.Int.Value =(aObject as TomDBChan).Int.Value检查它们是否相等,它没有指定(aObject为TomDBChan).Int.Value给LChan.Int.Value。