2010-03-12 20 views
29

Was ist die beste Vorgehensweise für die Implementierung von IDisposable?Wann sollte IDisposable implementiert werden?

Ist die beste Faustregel, um es zu implementieren, wenn Sie ein verwaltetes Objekt in der Klasse haben, oder hängt es davon ab, ob das Objekt in der Klasse erstellt oder gerade übergeben wurde? Sollte ich das auch für Klassen mit keinen verwalteten Objekten tun?

+2

@Earwicker: Wenn Sie mehr als ich zu diesem Thema gefunden haben, dann würde ich es begrüßen, dass Sie es mit mir teilen. – Bobby

+2

http://stackoverflow.com/search?q=IDisposable+eigentümer –

Antwort

26

Wenn Sie unmanaged Objekte dann ja meinen, sollten Sie es implementieren, wenn Sie eine oder mehrere nicht verwaltete Ressourcen haben, die Sie in Ihrer Klasse behandeln. Sie sollten das Muster auch verwenden, wenn Sie sich möglicherweise an Objekten halten, die IDisposable selbst sind, und stellen Sie sicher, sie zu entsorgen, wenn Ihre Klasse entsorgt wird.

(vereinbart, dass diese Frage schon oft genug wie laufen einen kleinen Drucker keine Tinte sollten sie gedruckt werden ... gefragt worden)

6

Sie sollten IDisposable implementieren, wenn Ihre Klasse Ressourcen enthält, die Sie freigeben möchten, wenn Sie sie nicht mehr verwenden.

0

Wenn es Eigenschaften hat, die auch entsorgt werden müssen.

6

Wenn Ihre Klasse enthält nicht verwalteten Objekte, Ressourcen, geöffneten Dateien oder Datenbankobjekte , müssen Sie IDisposable implementieren.

4

Ich denke, the docs sind ziemlich klar darüber, was IDisposable ist gut für.

Die primäre Verwendung dieser Schnittstelle ist , um nicht verwaltete Ressourcen freizugeben. Der Garbage Collector automatisch gibt den Speicher frei, der einem verwalteten Objekt zugewiesen ist, wenn dieses Objekt nicht länger verwendet wird. Es ist jedoch nicht möglich, vorherzusagen, wenn Müll Sammlung auftreten wird. Darüber hinaus der Garbage Collector hat keine Kenntnisse von nicht verwalteten Ressourcen wie Fenster behandelt, oder öffnen Sie Dateien und Streams.

Es hat sogar ein Beispiel. In diesem Beispiel enthält die Klasse, die IDisposable implementiert, ein Handle. Ein Handle muss freigegeben werden, wenn es nicht mehr verwendet wird. Dies geschieht in der Dispose() Methode. Der Benutzer dieser Klasse sieht also, dass er IDisposable implementiert und weiß, dass die Klasse explizit entsorgt werden muss, wenn sie nicht mehr benötigt wird (so dass das Handle freigegeben werden kann). Es ist eine bewährte Methode (d. H. Regel), dass Sie immer Dispose() auf IDisosable Instanzen aufrufen sollten, wenn die Instanz nicht mehr benötigt wird.

10

Während alle (nicht verwalteten) Ressourcen erwähnt haben, muss ich noch etwas hinzufügen: Ich benutze es, wenn ich Event-Handler-Hookups eliminieren muss, die sonst verhindern würden, dass eine Klasse den Bereich verlässt und Garbage Collected wird.

Als Beispiel habe ich einen Dienst, der in eine untergeordnete Ansicht injiziert wird, die untergeordnete Ansicht wird verschiedene asynchrone beendete Typ Ereignisse auf dem Dienst abonnieren. Der Besitzer dieser Kindansicht hat keine Ahnung, was der konkrete Typ ist, er hat es einfach als Schnittstelle. Der Dienst kann zu irgendeinem willkürlichen Zeitpunkt in der Zukunft aus dem Rahmen fallen, und ich möchte nicht, dass er herumhängt, weil er nicht gecallt wird. Nach dem Entfernen dieser untergeordneten Ansicht wird der Besitzer Dispose aufrufen, um ihm die Möglichkeit zu geben, Event-Handler auszuhängen. Hier ist ein leicht erfundener (und sehr Pseudocode) Beispiel, beachten Sie, wie die Schnittstelle für die Kindansicht auch IDisposable implementiert.

public class OwnerView { 

    public OwnerView() { 
     _childView = new ChildView(myServiceReference); 
    } 

    public void CloseChildView() { 
     if (childView != null) { 
      _childView.Close(); 
      _childView.Dispose(); 
     } 

     _childView = null; 
    } 

    private IChildView _childView; 
} 

public class ChildView : IChildView { 

    public ChildView(MyService serviceRef) { 
     _serviceRef = serviceRef; 
     _serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler); 
    } 

    public void IDisposable.Dispose() { 
     _serviceRef -= someEventHandler; 
    } 

    private MyService _serviceRef; 
} 

public interface IChildView : IDisposable { 
    void DoSomething(); 
    ... etc ... 
} 

Es gibt weit mehr Autorität Kommentare über diese von den anderen auf SO, wie Do event handlers stop garbage collection from occuring? und Garbage collection when using anonymous delegates for event handling. Sie können auch diesen Artikel codeproject Artikel überprüfen.

Verwandte Themen