C#/Java "Try/Finally/Catch" equivalent construct in Delphi
In Delphi, how can you use try, finally, and catch together? A Java/C# equivalent would look something like:
try {
// Open DB connection, start transaction
} catch (Exception e) {
// Roll back DB transaction
} finally {
// Close DB connection, commit transaction
}
If you try this in Delphi, you can either use try/finally or try/exc开发者_开发知识库ept; but never all three together. I would like code like the following (which doesn't compile):
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
In Delphi you can use the following pattern:
// initialize / allocate resource (create objects etc.)
...
try
try
// use resource
...
except
// handle exception
...
end;
finally
// free resource / cleanup
...
end
write
try
// allocate resource here
try
finally
// free resource here
end;
except
// handle exception here
end;
While nesting the try...except
inside a try...finally
(or vice versa) directly answers the question I would like to point out that original question, regardless of what language you are using, is mixing the concerns of error handling and resource management. Try...except
and try...finally
are ugly. They distract you from what your code is doing. A better approach is to extract error handling into a separate method:
procedure Read(Connection: TDBConnection);
begin
try
//Read DB
except
//Handle Exception
end;
end;
procedure ReadRecord;
begin
DBConnection.Open;
Read(DBConnection);
DBConnection.Close;
end;
Now your error handling is self-contained and can be ignored so you can concentrate your attention on the happy path.
Wait! What about the open
and close
? What if they raise exceptions?
Simple. Wrap those operations in try...except functions and handle them as well. It shouldn't be necessary. If the DB library your using is worth anything an exception in an open
or close
won't leave the connection in an unknown state. Then again, exceptions are there for the things you don't expect.
The same technique can be used with any resource: object creation, file access, etc. When the body of your function is guaranteed not to raise an exception try...finally
is unnecessary.
There is, of course, function call overhead but in most cases it is negligible and your error handling functions should be small enough to let the compiler inline them.
精彩评论