Уникальная особенность интерфейса IDisposable заключается в том, что язык фактически предоставляет для него определенную конструкцию: блок «using»:
public void SomeMethod()
{
using(IDisposable myDisposable = new SomeClassThatImplementsIDisposable())
{
//Do something with your disposable...
}
//And, it's out of scope here
}
Это немного синтаксического сахара, в котором то, что происходит на самом делеthis:
public void SomeMethod()
{
IDisposable myDisposable = new SomeClassThatImplementsIDisposable();
try
{
//Do something with your disposable...
}
finally
{
myDisposble.Dispose();
}
//And, it's out of scope here
}
Итак, когда вы реализуете IDisposable, вы предоставляете клиентам вашего класса способ использовать его там, где они могут гарантировать (по большей части), что очистка, которую вы планируете для своего класса на самом делеслучается.
Это наиболее часто встречающееся и критическое в классах, которые содержат неуправляемые ресурсы.Например, если бы ваш класс содержал соединение с базой данных, вы бы не хотели, чтобы клиенты выходили за его пределы, даже не закрывая соединение, поскольку это было бы утечкой памяти.Использование IDisposable выше также гарантирует, что если генерируется какое-то исключение, «finally», подразумеваемое «using ()», вызовет ваше распоряжение, чтобы вы могли хотя бы очистить.
Тем не менее, безусловно, естьситуации, когда вы можете использовать его для управляемых ресурсов.Один пример, который приходит на ум с самого начала, - это если экземпляр вашего класса слушает события, вызванные экземпляром класса с более длительным сроком жизни, чем ваш.Без утилизации это также создает утечку памяти (распространенная проблема в .NET).
Так что, вообще говоря, я бы использовал ее в обстоятельствах, когда было бы плохо, если экземпляр вашего класса вышел изобласть без выполнения всего кода очистки.Реализация IDisposable объявляет всем клиентам вашего класса, что есть ресурсы, которые он содержит, и которые необходимо правильно утилизировать.