Beginnen Sie mit diesen einfachen Klassen ...
Angenommen, ich habe eine einfache Reihe solcher Klassen:
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 Bushat a Driver, das Driverhat zwei Shoes, jeder Shoehat a Shoelace. Alles sehr dumm.
Fügen Sie Shoelace ein IDisposable-Objekt hinzu
Später entscheide ich, dass eine Operation auf dem ShoelaceMultithreading ausgeführt werden kann, also füge ich eine hinzu, EventWaitHandlemit der die Threads kommunizieren können. So Shoelacesieht es jetzt aus:
class Shoelace
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
// ... other stuff ..
}
Implementieren Sie IDisposable auf Shoelace
Jetzt beschwert sich Microsoft FxCop jedoch: "Implementieren Sie IDisposable auf 'Shoelace', da Mitglieder der folgenden IDisposable-Typen erstellt werden: 'EventWaitHandle'."
Okay, ich implementiere IDisposableweiter Shoelaceund meine nette kleine Klasse wird zu diesem schrecklichen Durcheinander:
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;
}
}
Oder (wie von Kommentatoren hervorgehoben), da es Shoelaceselbst keine nicht verwalteten Ressourcen gibt, könnte ich die einfachere Entsorgungsimplementierung verwenden, ohne den Dispose(bool)und Destructor zu benötigen :
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);
}
}
Beobachten Sie entsetzt, wie sich IDisposable ausbreitet
Richtig, das ist behoben. Aber jetzt wird sich FxCop beschweren, dass ein Shoeschafft Shoelace, so Shoemuss es IDisposableauch sein.
Und Driverschafft muss Shoeso Driversein IDisposable. Und Busschafft Driverso Busmuss sein IDisposableund so weiter.
Plötzlich verursacht meine kleine Änderung an Shoelaceviel Arbeit und mein Chef fragt sich, warum ich zur Kasse gehen muss Bus, um eine Änderung vorzunehmen Shoelace.
Die Frage
Wie verhindern Sie diese Ausbreitung IDisposableund stellen dennoch sicher, dass Ihre nicht verwalteten Objekte ordnungsgemäß entsorgt werden?