Целью интерфейса IDisposable
является упорядоченное упорядочение неуправляемых ресурсов. Он идет рука об руку с ключевым словом using
, который определяет область, по истечении которой данный ресурс удаляется.
Потому что этот мехнизм настолько опрятен, что я неоднократно испытывал желание внедрить классы IDisposable
, чтобы иметь возможность злоупотреблять этим механизмом способами, для которых он не предназначен. Например, можно было бы реализовать классы для обработки вложенных контекстов, таких как:
class Context : IDisposable
{
// Put a new context onto the stack
public static void PushContext() { ... }
// Remove the topmost context from the stack
private static void PopContext() { ... }
// Retrieve the topmost context
public static Context CurrentContext { get { ... } }
// Disposing of a context pops it from the stack
public void Dispose()
{
PopContext();
}
}
Использование кода вызова может выглядеть так:
using (Context.PushContext())
{
DoContextualStuff(Context.CurrentContext);
} // <-- the context is popped upon leaving the block
(Обратите внимание, что это всего лишь пример, а не тема этого вопроса.)
Тот факт, что Dispose()
вызывается из области действия оператора using
, также может быть использован для реализации всех видов вещей, которые зависят от области видимости, например. таймеры. Это также можно было бы использовать с помощью конструкции try ... finally
, но в этом случае программисту пришлось бы вручную вызвать какой-либо метод (например, Context.Pop
), который конструктор using
мог бы сделать для thon.
Это использование IDisposable
не совпадает с его назначением как указано в документации, однако искушение сохраняется.
Есть ли конкретные причины, чтобы проиллюстрировать, что это плохая идея и развеять мои фантазии навсегда, например, осложнения с сборкой мусора, обработку исключений и т.д. Или я должен идти дальше и побаловать себя, злоупотребляя этой концепцией языка таким образом?