使用嵌套的“try / finally”“try / except”语句

时间:2010-08-19 22:19:39

标签: delphi try-finally try-except

我已经在StackOverflow上看到了这个代码:

with TDownloadURL.Create(nil) do
  try
    URL := 'myurltodownload.com';
    filename := 'locationtosaveto';
    try
      ExecuteTarget(nil);
    except
      result := false;
    end;
    if not FileExists(filename) then
      result := false;
  finally
    free;
  end;

不能简化为:

 Result:= FALSE;               <--------- Compiler complains
 DeleteFile(Dest);
 dl:= TDownloadURL.Create(NIL);
 TRY
   dl.URL:= URL;
   dl.FileName:= Dest;
   dl.ExecuteTarget(NIL);           
   Result:= FileExists(Dest);
 FINALLY
   dl.Free;
 END;

最终结果:= ......如果在'ExecuteTarget'中出现问题,将永远不会被执行,因为程序将直接跳转到'finally'。对?因此,该函数将返回FALSE。我做错了吗?


PS:

  1. 我打算在一个帖子中使用这段代码。
  2. 我刚把这个函数放在Delphi中,编译器抱怨第一行:“赋值从未使用过。”

3 个答案:

答案 0 :(得分:12)

不同之处在于您的第二个示例将异常传递回调用方,而原始陷阱则将其返回false并返回false。我将这种编码风格描述为“我不在乎它失败的原因,我只关心它是否成功”。在某些情况下这可能是合理的(比如尝试下载更新)。

因此,您的代码与原始代码非常不同 - 您希望调用者能够处理原始代码所没有的异常。

此外,编译器投诉是因为您的代码中没有分支 - 如果作品和结果由第二个作业确定,或者您有异常且结果无关紧要。

Result := FALSE; //   <--------- Compiler complains
DeleteFile(Dest);
dl := TDownloadURL.Create(nil);
try
   dl.URL := URL;
   dl.FileName := Dest;
   dl.ExecuteTarget(nil);
   Result := FileExists(Dest);
finally
   dl.Free;
end;

答案 1 :(得分:2)

在原始版本中,如果ExecuteTarget抛出异常,它仍然会测试文件名是否存在。

在你的情况下,如果ExecuteTarget抛出异常,结果总是为假。

此外,除非您跳过原始行,否则如果ExecuteTarget成功且文件存在,则永远不会设置result

答案 2 :(得分:1)

第一个版本只是吃异常并且从不向上级调用者提出,它将异常视为错误返回。对于您的简单版本,将抛出异常。