Я майже впевнений, що відповідь ТАК. Якщо я використовую блок "Спробуйте остаточно", але не використовую блок "Catch", то будь-які винятки будуть "Bubble". Правильно?
Якісь думки щодо практики взагалі?
Сет
Я майже впевнений, що відповідь ТАК. Якщо я використовую блок "Спробуйте остаточно", але не використовую блок "Catch", то будь-які винятки будуть "Bubble". Правильно?
Якісь думки щодо практики взагалі?
Сет
Відповіді:
Так, це абсолютно буде. Припустимо, що ваш finally
блок не кидає винятку, звичайно, у такому випадку це ефективно "замінить" той, який був викинутий.
Якісь думки щодо практики взагалі?
Так. Будьте обережні . Коли ваш остаточний блок запущений, цілком можливо, що він працює, оскільки було кинуто необроблений, несподіваний виняток . Це означає, що щось порушено , і щось абсолютно несподіване може статися .
У цій ситуації, мабуть, випадок, що вам взагалі не слід запускати код. Код остаточно блоку може бути побудований так, щоб припустити, що підсистеми, від яких він залежить, є здоровими, бо насправді вони можуть бути глибоко зламані. Код в остаточному блоці може погіршити ситуацію.
Наприклад, я часто бачу такі речі:
DisableAccessToTheResource();
try
{
DoSomethingToTheResource();
}
finally
{
EnableAccessToTheResource();
}
Автор цього кодексу думає: "Я роблю тимчасові мутації до стану світу; мені потрібно відновити стан до того, яким він був до того, як мене покликали". Але давайте подумаємо про всі способи, як це могло піти не так.
По-перше, доступ до ресурсу вже може бути відключений абонентом; у такому випадку цей код знову вмикає його, можливо, передчасно.
По-друге, якщо DoSomethingToTheResource кидає виняток, це правильно зробити, щоб дозволити доступ до ресурсу ??? Код, який управляє ресурсом, несподівано порушується . Цей код говорить, по суті, "якщо код управління порушений, переконайтеся, що інший код може викликати цей зламаний код якомога швидше, так що він також може жахливо вийти з ладу ". Це здається поганою ідеєю.
По-третє, якщо DoSomethingToTheResource кидає виняток, то як ми можемо знати, що EnableAccessToTheResource також не викине виключення? Яка б жахливість не мала, використання ресурсу також може вплинути на код очищення; в цьому випадку вихідний виняток буде втрачено, і проблему буде важче діагностувати.
Я схильний писати такий код без використання пробних блоків:
bool wasDisabled = IsAccessDisabled();
if (!wasDisabled)
DisableAccessToTheResource();
DoSomethingToTheResource();
if (!wasDisabled)
EnableAccessToTheResource();
Зараз держава не мутується, якщо цього не потрібно. Тепер стан абонента не псується. І тепер, якщо DoSomethingToTheResource виходить з ладу, ми не повторно вмикаємо доступ. Ми припускаємо, що щось глибоко порушено, і не ризикуємо погіршити ситуацію, намагаючись зберегти запущений код. Нехай абонент вирішує проблему, якщо зможе.
Тож коли корисно запустити остаточний блок? По-перше, коли очікується виняток. Наприклад, ви можете очікувати, що спроба блокування файлу може бути невдалою, оскільки його заблокував хтось інший. У цьому випадку є сенс зловити виняток і повідомити про це користувачеві. У цьому випадку зменшується невизначеність того, що порушено; Ви навряд чи погіршите ситуацію, прибираючи.
По-друге, коли ресурс, який ви прибираєте, - це дефіцитний системний ресурс. Наприклад, є сенс закрити ручку файлу остаточно блоком. ("Використання" - це, звичайно, лише інший спосіб написання блоку спробу. Нарешті.) Вміст файлу може бути пошкодженим, але зараз ви нічого не можете з цим зробити. Обробку файлів врешті-решт буде закрито, тому це може бути швидше, ніж пізніше.