Так, Dispose
буде називатися. Він викликається, як тільки виконання залишає область using
блоку, незалежно від того, якими засобами потрібно було залишити блок, будь то закінчення виконання блоку, return
заява чи виняток.
Як правильно вказує @Noldorin, використання using
блоку в коді збирається в try
/ finally
, з викликом Dispose
у finally
блоці. Наприклад, наступний код:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
фактично стає:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Отже, оскільки finally
це гарантовано виконується після try
завершення виконання блоку, незалежно від шляху його виконання, Dispose
гарантовано викликається, незалежно від того.
Для отримання додаткової інформації дивіться цю статтю MSDN .
Додаток:
Ще трохи застереження: адже, оскільки Dispose
він гарантовано називається, майже завжди є хорошою ідеєю гарантувати, що Dispose
ніколи не викидає виняток при здійсненні IDisposable
. На жаль, в основній бібліотеці є кілька класів, які закидають за певних обставин, коли Dispose
викликається - я дивлюся на вас, довідник служби WCF / клієнтський проксі! - і коли це трапляється, може бути дуже важко відстежити вихідний виняток, якщо Dispose
його викликали під час розмотування стека винятків, оскільки початковий виняток проковтується на користь нового винятку, що генерується Dispose
викликом. Це може бути шалено засмучує. Або це розчаровує розум? Одне з двох. Можливо і те й інше.