一开始你的代码看起来有点奇怪,我错过了创建X的部分。
X := CreateAnX
try
DoSomeThing(X);
finally
FreeAndNil(x);
end;
这很重要。因为如果你有像这样的代码
// don't do something like this
try
X := CreateAnX
DoSomeThing(X);
finally
FreeAndNil(x);
end;
你可以运气好,它能够正常工作。但如果构建失败了,你可能会“幸运”地遭遇访问冲突,或者你就是倒霉,在完全不同的代码位置有时会发生访问违规。
另一种选择是
X := nil;
try
X := CreateAnX
DoSomeThing(X);
finally
FreeAndNil(x);
end;
在编程中使用 except 取决于你的意图。当你想捕获每一个异常并清除所有调用代码的问题(使用 try finally),那么外层 except 块就是正确的选择。
try
X := CreateAnX
try
DoSomeThing(X);
finally
FreeAndNil(x);
end;
except
on e: Exception do
LogException(e)
end;
但是在想要捕获所有错误时,一定要考虑清楚。例如(我经常看到这种错误),不要在Indy OnExecute处理程序中这样做。你必须使用类似这样的东西
try
X := CreateAnX
try
DoSomeThing(X);
finally
FreeAndNil(x);
end;
except
on EIdException do
raise;
on e: Exception do
LogException(e)
end;
如果你预期会有异常,因为你抛出了它或者(比如)一个对话可能会失败,那么请尝试找到最内层的位置去捕获这个错误:
X := CreateAnX
try
DoSomeThing(X);
try
i := StrToInt(X.Text);
except
on EConvertError do
i := 0;
end;
finally
FreeAndNil(x);
end;
不要这样做
X := CreateAnX
try
try
DoSomeThing(X);
i := StrToInt(X.Text);
except
on EConvertError do
i := 0;
end;
finally
FreeAndNil(x);
end;
只有在你也预期DoSomeThing会抛出EConvertError时才这样做。如果DoSomeThing抛出了EConvertError而你并没有预期,那么你的代码存在严重问题,需要进行修正。在这种情况下,请确保用户可以保存他的工作(可能是作为一个备份,因为他的工作可能被损坏),并确保你获取到有关问题的信息。
至少使用try except来处理异常,而不是隐藏它们。