С#/Java "Try/Finally/Catch" эквивалентная конструкция в Delphi
В Delphi, как вы можете использовать try, наконец, и поймать вместе? Эквивалент Java/С# выглядит примерно так:
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
Ответы
Ответ 1
В Delphi вы можете использовать следующий шаблон:
// initialize / allocate resource (create objects etc.)
...
try
try
// use resource
...
except
// handle exception
...
end;
finally
// free resource / cleanup
...
end
Ответ 2
написать
try
// allocate resource here
try
finally
// free resource here
end;
except
// handle exception here
end;
Ответ 3
При вложении try...except
внутри a try...finally
(или наоборот) непосредственно ответит на вопрос, который я хотел бы указать, что исходный вопрос, независимо от того, какой язык вы используете, смешивает проблемы обработки ошибок и ресурсов управление. try...except
и try...finally
являются уродливыми. Они отвлекают вас от того, что делает ваш код. Лучшим подходом является извлечение обработки ошибок в отдельный метод:
procedure Read(Connection: TDBConnection);
begin
try
//Read DB
except
//Handle Exception
end;
end;
procedure ReadRecord;
begin
DBConnection.Open;
Read(DBConnection);
DBConnection.Close;
end;
Теперь ваша обработка ошибок является автономной и ее можно игнорировать, поэтому вы можете сосредоточить свое внимание на счастливом пути.
Подождите! Как насчет open
и close
? Что делать, если они вызывают исключения?
Simple. Оберните эти операции в try... кроме функций и обработайте их. Это не обязательно. Если библиотека БД, используемая вами для использования, является чем-то исключением в open
или close
, не оставит соединение в неизвестном состоянии. Опять же, исключения существуют для вещей, которые вы не ожидаете.
Тот же метод может использоваться с любым ресурсом: создание объекта, доступ к файлу и т.д. Когда тело вашей функции гарантировано не поднимает исключение, try...finally
не требуется.
Есть, конечно, служебные вызовы функций, но в большинстве случаев они ничтожны, а ваши функции обработки ошибок должны быть достаточно малы, чтобы компилятор мог объединить их.