以下代码为例:
procedure TForm1.Button1Click(Sender: TObject);
var
Obj: TSomeObject;
begin
Screen.Cursor:= crHourGlass;
Obj:= TSomeObject.Create;
try
// do something
finally
Obj.Free;
end;
Screen.Cursor:= crDefault;
end;
如果 //do some
部分发生错误,我认为创建的 TSomeObject 将不会被释放,并且 Screen.Cursor 仍将卡在沙漏中,因为在到达这些行之前代码就被破坏了?
现在,除非我弄错了,否则应该有一个 Exception 语句来处理任何此类错误的发生,例如:
procedure TForm1.Button1Click(Sender: TObject);
var
Obj: TSomeObject;
begin
try
Screen.Cursor:= crHourGlass;
Obj:= TSomeObject.Create;
try
// do something
finally
Obj.Free;
end;
Screen.Cursor:= crDefault;
except on E: Exception do
begin
Obj.Free;
Screen.Cursor:= crDefault;
ShowMessage('There was an error: ' + E.Message);
end;
end;
现在,除非我做了一些非常愚蠢的事情,否则没有理由在 Final block 及其之后以及 Exception block 中使用相同的代码两次。
基本上,我有时会执行一些可能与我发布的第一个示例类似的过程,如果出现错误,光标就会像沙漏一样卡住。添加异常处理程序会有所帮助,但这似乎是一种肮脏的方法 - 它基本上忽略了 Final block ,更不用说从 Final 到 Exception 部分复制粘贴的丑陋代码了。
我仍在学习 Delphi,所以如果这看起来是一个简单的问题/答案,我深表歉意。
应该如何正确编写代码来处理语句并正确释放对象和捕获错误等?
最佳答案
您只需要两个 try/finally
block :
Screen.Cursor:= crHourGlass;
try
Obj:= TSomeObject.Create;
try
// do something
finally
Obj.Free;
end;
finally
Screen.Cursor:= crDefault;
end;
要遵循的准则是,您应该使用 finally
而不是 except
来保护资源。正如您所观察到的,如果您尝试使用 except
来执行此操作,那么您将被迫编写两次最终代码。
一旦进入try/finally
block ,无论try
之间发生什么,finally
部分中的代码都保证运行。 最后
。
因此,在上面的代码中,外部 try/finally
确保在遇到任何异常时恢复 Screen.Cursor
。同样,内部 try/finally
确保 Obj
在其生命周期内发生任何异常时被销毁。
如果您想处理异常,那么您需要一个不同的 try/except
block 。但是,在大多数情况下,您不应该尝试处理异常。只需让它传播到主应用程序异常处理程序,该处理程序将向用户显示一条消息。
如果您处理异常以降低调用链,那么调用代码将不知道它调用的代码已失败。
关于delphi - 如何正确编写Try..Finally..Except语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6601147/