当前位置 : 主页 > 编程语言 > delphi >

delphi – 是否存在一般性E未捕获的异常:异常?

来源:互联网 收集:自由互联 发布时间:2021-06-23
我想知道是否存在异常/错误,这会使您的代码跳转到一个except块但不会被E:exception处理. try i := StrToInt(s); {...do a lot more...} except on E : EConvertError do begin ShowMessage('You need to input a valid numb
我想知道是否存在异常/错误,这会使您的代码跳转到一个except块但不会被E:exception处理.

try
   i := StrToInt(s);
   {...do a lot more...}
 except
   on E : EConvertError do begin
     ShowMessage('You need to input a valid number.');
   end;
   on E : Exception do begin
     ShowMessage('Something went wrong.');
     Raise; 
   end;
 end;

有没有一种方法可以让一个程序错误地忽略这个除了块之外的两个语句?
或者我应该这样做:

try
   i := StrToInt(s);
   {...do a lot more...}
 except
   on E : EConvertError do begin
     ShowMessage('You need to input a valid number.');
   end;
   else begin  // swapped on e : Exception with else
     ShowMessage('Something went wrong.');
     Raise; 
   end;
 end;
你可以抛出任何派生自TObject的东西.为了捕获每个这样的类,您需要在on语句中指定TObject.

从documentation:

Exception types are declared just like other classes. In fact, it is possible to use an instance of any class as an exception, but it is recommended that exceptions be derived from the SysUtils.Exception class defined in SysUtils.

实际上,我知道没有代码可以抛出任何不是从Exception派生的东西,尽管@TLama在评论中指出了旧版已弃用的VCL类中的一个示例.当然StrToInt只会抛出Exception后代.

如果您不需要访问异常对象,则可以使用plain except子句而不使用on语句.

try
  ....
except 
  // deal with all exceptions
end;

或者你可以使用on语句的else子句作为catch all,再次你不会立即访问异常对象.

否则,您可以为要捕获的异常指定基类.例如,E:TObject捕获从TObject派生的所有内容.

因此,正如我们所看到的,可能会抛出不是从Exception派生的东西.但你必须问自己,你的代码是否曾经这样做过?如果没有,那么在catch catch all handler中测试Exception是最有意义的.这将使您可以访问Exception的成员.当然,人们确实想知道为什么你有一个捕获所有异常处理程序.它们的存在往往表明设计不佳.

继续StrToInt的主题,你只需要捕获EConvertError.这就是转换失败时引发的问题.您应该忽略任何其他异常类,因为在您的示例中,代码将不知道如何处理其他任何异常.编写异常处理代码的目标之一是处理您知道如何处理的内容,并忽略其他所有内容.

事实上,TryStrToInt就是你需要的:

if TryStrToInt(s, i) then
  // do stuff with i
else
  // deal with conversion error

这消除了处理任何异常的需要,并使您的代码更具可读性.

我知道StrToInt只是一个例子,但它很好地证明了试图避免处理异常的好处.

网友评论