Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi中C/Java的Try/Finally/Catch等价结构_Delphi_Exception Handling - Fatal编程技术网

Delphi中C/Java的Try/Finally/Catch等价结构

Delphi中C/Java的Try/Finally/Catch等价结构,delphi,exception-handling,Delphi,Exception Handling,在Delphi中,如何使用try、finally和catch?Java/C等价物的外观如下所示: try { // Open DB connection, start transaction } catch (Exception e) { // Roll back DB transaction } finally { // Close DB connection, commit transaction } 如果您在Delphi中尝试此功能,则可以使用try/finall

在Delphi中,如何使用try、finally和catch?Java/C等价物的外观如下所示:

try {
    // Open DB connection, start transaction
} catch (Exception e) {
    // Roll back DB transaction
} finally {
    // Close DB connection, commit transaction
}
如果您在Delphi中尝试此功能,则可以使用try/finally或try/except;但这三者永远不会在一起。我想要下面这样的代码,它不会编译:

try
    // Open DB connection, start transaction
except on e: Exception do
begin
    // Roll back transaction
end
finally // Compiler error: expected "END" not "finally"
begin
    // Commit transaction
end

在Delphi中,可以使用以下模式:

// initialize / allocate resource (create objects etc.)
...
try
  try
    // use resource
    ...
  except
    // handle exception
    ...
  end;
finally
  // free resource / cleanup
  ...
end

当嵌套try…时,除了try…最终,或者反之亦然,直接回答了这个问题。我想指出,最初的问题,无论您使用的是什么语言,都混合了错误处理和资源管理的关注点。尝试…除了和尝试…最终都是丑陋的。它们会分散您对代码所做工作的注意力。更好的方法是将错误处理提取到单独的方法中:

procedure Read(Connection: TDBConnection);
begin
  try
    //Read DB
  except
    //Handle Exception
  end;
end;

procedure ReadRecord;
begin
  DBConnection.Open;
  Read(DBConnection);
  DBConnection.Close;
end;
现在,您的错误处理是自包含的,可以忽略,这样您就可以将注意力集中在快乐的道路上

等等!开盘和收盘怎么样?如果他们提出例外情况呢

简单。将这些操作包装在try…函数中,并处理它们。应该没有必要。如果您使用的DB库值得任何东西,则打开或关闭时的异常不会使连接处于未知状态。再说一次,你不期望的事情也有例外

同样的技术也可以用于任何资源:对象创建、文件访问等。当您的函数体保证不会引发异常时,尝试…最后是不必要的


当然,函数调用开销是存在的,但在大多数情况下,它可以忽略不计,并且错误处理函数应该足够小,以便让编译器内联它们。

与mjustin的答案功能相同,但我更喜欢他的答案-首先捕获异常,然后在最后捕获最后一个块,这使它更具可读性。或者我只是有偏见,因为这是Java/C风格:mjustin的答案不会捕获析构函数中的异常。“这是更好的方法。那没什么关系,”加布说。如果析构函数抛出异常,那么您已经注定要失败。你的程序绝对无法修复导致那样错误的问题。Jim McKeeth在finally block中谈到处理异常的问题时,有一段关于延迟异常处理的精彩视频。RobK:如果析构函数释放资源,堆引发异常,你是对的。如果在某个对象的销毁通知中调用的某个用户编写的方法导致了您想要捕获的非致命错误,那么这就是您的错误所在。太棒了。我喜欢嵌套如何模仿try,catch,finally的预期可读性,就像我在Java/C中习惯的那样。除了它增加了不必要的缩进级别。我真的希望他们能够写try..finally..except..end,如果按照随机顺序(取决于首先处理的内容),甚至更好,但是如果可以做try..except A..finally..except B..end。就编码而言,这真的没有那么多,也不会给语言带来负担,但增加了一种美妙的触感。@hiver:你多久见过一次例外,最后真的很接近对方?好几次。典型的情况是,需要销毁一些临时对象并处理异常。但由于这种模式的丑陋性,人们通常只是在try和except子句中复制销毁代码。在这种情况下,finally没有用。因为finally和except在语义上完全不同,在Delphi中它们不能在同一个语句中。只需看看使用finally和except的RTL/VCL源及其比率。您几乎看不到它们附近的地方。不要将提交事务放在finally块中。如果发生异常,则不希望提交任何内容。您尤其不希望尝试提交已在前面的Exception块中回滚的事务。提交应该是try部分的最后一个操作。+1用于超越明显的问题。不幸的是,我的问题是纯句法的,而不是语义的。
procedure Read(Connection: TDBConnection);
begin
  try
    //Read DB
  except
    //Handle Exception
  end;
end;

procedure ReadRecord;
begin
  DBConnection.Open;
  Read(DBConnection);
  DBConnection.Close;
end;