Інтерфейс IDisposable має ключове значення для вивільнення ресурсів і виконує в C# дві важливі ролі:
Dispose()), що він більше не потрібен, аби той міг вивільнити некеровані ресурси або за потреби скинути свій внутрішній стан. Це відрізняється від звичного підходу до очищення, за якого збирач сміття прибирає все (передусім вивільняє памʼять).IDisposable підтримує інструкцію using, про яку йдеться у вправі resource-lifetime.Цілком можливо, хоч і малоймовірно, що Dispose() викликатимуть через інтерфейс у якійсь загальній процедурі очищення.
Найчастіше IDisposable трапляється в класах бібліотек, які обгортають ресурси операційної системи (некеровані), як-от System.IO.Stream і System.IO.TextReader. (Про Stream і TextReader йдеться в інших вправах).
public class TextHandler : IDispoable
{
private TextReader reader = new TextReader(...);
public void Dispose()
{
reader.Dispose();
}
}
Якщо клас, який ми використовуємо, реалізує інтерфейс IDispoable, потрібно подбати про те, щоб Dispose() було викликано (за допомогою блоків catch і finally), коли екземпляр більше не потрібен. Якщо клас має член, який реалізує IDisposable, то цілком імовірно, що й самому класу потрібно реалізувати IDisposable, щоб можна було викликати Dispose() і позбутися члена, який реалізує IDisposble.
public class Activity : IDisposable
{
private MyResource myResource;
public Activity()
{
myResource = new MyResource();
}
public void Perform()
{
try
{
myResource.BeUseful();
}
catch (Exception)
{
myResource.Dispose();
}
}
public void Dispose()
{
myResource.Dispose();
}
}
Інтерфейс IDisposable може бути корисним навіть тоді, коли некерованих ресурсів немає. Скажімо, у нас є довгоживучий обʼєкт, який вимагає, щоб короткоживучі обʼєкти реєструвалися в ньому, а потім скасовували реєстрацію, коли вони більше не потрібні. Реалізація IDisposable у короткоживучому обʼєкті попереджає розробника, який використовує цей клас, що Dispose() потрібно викликати в кінці життєвого циклу короткоживучого обʼєкта.
У документації ми побачимо згадки про патерн Dispose. Патерн Dispose передбачає виклик Dispose() із фіналізатора класу та правильну обробку вивільнення ресурсів у базових класах. Патерн Dispose розглядається в одній із наступних вправ.
Патерн Dispose здебільшого стосується некерованих ресурсів. Якщо ми використовуємо механізм P/Inovke і методи extern, потрібно розуміти, як і коли застосовувати патерн Dispose. Більшості розробників C# рідко доводиться мати справу з некерованими ресурсами безпосередньо в такий спосіб.