Так, 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викликом. Це може бути шалено засмучує. Або це розчаровує розум? Одне з двох. Можливо і те й інше.