Я вважаю це зловживанням використовуючої операцією. Я усвідомлюю, що на цій посаді я в меншості.
Я вважаю це зловживанням з трьох причин.
По-перше, тому що я очікую, що "використання" використовується для використання ресурсу та розпорядження ним, коли ви закінчите з ним . Зміна державної програми не використовуючи ресурс і змінити його назад не розпоряджатися нічого. Тому "використання" для мутації та відновлення стану - це зловживання; код вводить в оману випадковий читач.
По-друге, тому що я очікую, що "використання" використовуватиметься з ввічливості, а не від необхідності . Причина, по якій ви використовуєте "використання", щоб розпоряджатися файлом, коли ви закінчите з ним, не тому, що це потрібно зробити, а тому, що це ввічливо - хтось ще може чекати використання цього файлу, мовляв, "зроблено" тепер "- це морально правильна справа. Я очікую, що мені вдасться змінити коефіцієнт "використання", щоб використаний ресурс тримався довше, а потім був утилізований, і єдиний вплив цього - трохи незручності для інших процесів . Блок "використовуючий", який має семантичний вплив на стан програми є образливим, тому що він приховує важливу, необхідну мутацію стану програми в конструкції, яка виглядає так, що вона є для зручності та ввічливості, а не необхідності.
По-третє, дії вашої програми визначаються її станом; необхідність ретельного маніпулювання державою саме тому ведемо цю розмову в першу чергу. Розглянемо, як ми можемо проаналізувати вашу оригінальну програму.
Якщо ви донесли це до перегляду коду в моєму кабінеті, перше питання, яке я б поставив, - це чи справді правильно заблокувати фробла, якщо викинутий виняток? У вашій програмі очевидно, що ця річ агресивно повторно блокує фробу, незалежно від того, що відбувається. Це так? Виняток викинуто. Програма знаходиться в невідомому стані. Ми не знаємо, кинули Фу, Фіддл або Бар, чому вони кинули, або які мутації вони виконували іншим станом, які не були очищені. Чи можете ви переконати мене, що в тій жахливій ситуації завжди правильно зробити, щоб переблокувати?
Можливо, воно є, можливо, це не так. Моя думка полягає в тому, що з кодом, як він був написаний спочатку, рецензент коду знає задати питання . З кодом, який використовує "використання", я не знаю, щоб задати питання; Я припускаю, що блок "використовуючи" виділяє ресурс, використовує його трохи і ввічливо розпоряджається ним, коли це робиться, а не те, що закриваюча дужка блоку "використовуючи" мутує мій програмний стан у винятковій обставині, коли довільно багато були порушені умови узгодженості стану програми.
Використання блоку "використання" для семантичного ефекту робить цей фрагмент програми:
}
надзвичайно значущий. Коли я дивлюся на цю єдину близьку фігуру, я не відразу думаю, що "брекет має побічні ефекти, які мають далекосяжний вплив на глобальний стан моєї програми". Але коли ви зловживаєте "використанням", як це, раптом це відбувається.
Друге, що я хотів би запитати, чи бачив ваш оригінальний код - це "що станеться, якщо виключення буде викинуто після розблокування, але перед тим, як спробувати введено?" Якщо ви працюєте з неоптимізованою збіркою, компілятор, можливо, вставив інструкцію без операції перед спробою, і можливо, виняток переривання потоку може статися в неопераційному режимі. Це трапляється рідко, але це трапляється в реальному житті, особливо на веб-серверах. У такому випадку розблокування відбувається, але блокування ніколи не відбувається, оскільки виняток було кинуто перед спробою. Цілком можливо, що цей код є вразливим до цієї проблеми, і він насправді повинен бути написаний
bool needsLock = false;
try
{
// must be carefully written so that needsLock is set
// if and only if the unlock happened:
this.Frobble.AtomicUnlock(ref needsLock);
blah blah blah
}
finally
{
if (needsLock) this.Frobble.Lock();
}
Знову, можливо, так, може, і ні, але я знаю, щоб задати питання . З "використовуючою" версією вона може спричинити ту ж проблему: виняток переривання потоку може бути викинуто після блокування Frobble, але перед тим, як буде введено спробу захищеної області, пов'язаної з використанням. Але з "використовуючою" версією я припускаю, що це "так що?" ситуація. Прикро, якщо це трапиться, але я припускаю, що "використання" є тільки ввічливим, а не для мутації життєво важливого стану програми. Я припускаю, що якщо якийсь страшний виняток з переривання потоку трапиться в точно невідповідний час, тоді добре, збирач сміття очистить цей ресурс, врешті запустивши фіналізатор.