Почніть з цих простих занять ...
Скажімо, у мене простий набір таких класів:
class Bus
{
Driver busDriver = new Driver();
}
class Driver
{
Shoe[] shoes = { new Shoe(), new Shoe() };
}
class Shoe
{
Shoelace lace = new Shoelace();
}
class Shoelace
{
bool tied = false;
}
A Bus
має a Driver
, Driver
має два Shoe
s, кожен Shoe
має a Shoelace
. Все дуже нерозумно.
Додайте об’єкт, який не використовується, в Shoelace
Пізніше я вирішую, що деяка операція над програмою Shoelace
може бути багатопотоковою, тому я додаю EventWaitHandle
потоки для спілкування з ними. Отже, Shoelace
тепер виглядає так:
class Shoelace
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
// ... other stuff ..
}
Реалізуйте IDisposable на шнурці
Але тепер FxCop Microsoft поскаржиться: "Впровадьте IDisposable на" Shoelace ", оскільки він створює членів таких типів IDisposable:" EventWaitHandle "."
Гаразд, я впроваджую IDisposable
далі, Shoelace
і мій класний маленький клас стає цим жахливим безладом:
class Shoelace : IDisposable
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Shoelace()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (waitHandle != null)
{
waitHandle.Close();
waitHandle = null;
}
}
// No unmanaged resources to release otherwise they'd go here.
}
disposed = true;
}
}
Або (як наголошують коментатори), оскільки Shoelace
сам по собі не має керованих ресурсів, я міг би скористатися більш простою реалізацією розпорядження, не потребуючи Dispose(bool)
і Destructor:
class Shoelace : IDisposable
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
public void Dispose()
{
if (waitHandle != null)
{
waitHandle.Close();
waitHandle = null;
}
GC.SuppressFinalize(this);
}
}
Дивіться з жахом, як розповсюджується ID
Правильно, це виправлено. Але тепер FxCop поскаржиться на те, що Shoe
створює Shoelace
, так Shoe
має бути IDisposable
теж.
І Driver
творити Shoe
так Driver
треба IDisposable
. І Bus
творити Driver
так Bus
треба IDisposable
і так далі.
Раптом моя невелика зміна на Shoelace
викликає у мене багато роботи, і мій начальник цікавиться, чому мені потрібно оформити замовлення, Bus
щоб зробити зміни Shoelace
.
Питання
Як ви запобігаєте цьому розповсюдженню IDisposable
, але все ж забезпечуєте правильне розміщення ваших некерованих об'єктів?