起初您的代码看起来有点奇怪。我怀念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),那么外部异常块就是要走的路
try
X := CreateAnX
try
DoSomeThing(X);
finally
FreeAndNil(x);
end;
except
on e: Exception do
LogException(e)
end;
但是,当您想要捕获所有错误时,请始终考虑它。举个例子(我经常认为它是错误的)不要以这种方式在 Indy OnExecute-handler 中执行此操作。在那里你必须使用这样的东西
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 并且您没有预料到它,那么您的代码存在需要更正的严重问题。在这种情况下,请确保用户可以保存他的工作(可能作为副本,因为他的工作可能会被损坏)并确保您获得有关问题的信息。
至少尝试 except 是为了处理异常而不是隐藏它们。