Verwendung von IDisposable Zum Abbestellen eines Ereignisses - Muss ich andere Dinge in den Weg legen?

8

Ich habe die folgende Klasse

%Vor%

Die Frage ist nun, ob ich Dispose() method richtig implementiere? Oder muss ich alle anderen verwalteten Objekte manuell disponieren, nur weil ich explizit Dispose() ?

definiert habe

Ich schätze, dass der GC schlau genug ist, um sich selbst zu entledigen (außer dem Event-Abonnement), auch ohne dass ich es manuell mache. Habe ich Recht?

    
Graviton 13.01.2010, 06:34
quelle

2 Antworten

8

Wenn Sie mit der Wahl des Abonnierens im Konstruktor gehen, dann sieht das vernünftig aus. Ich würde Joshs Gefühle wiederholen, dass es nicht der beste Ansatz ist. Auf der anderen Seite kann es der einfachste Weg sein, um Ihr Ziel zu erreichen, was immer eine gute Sache ist. Ich werde nicht so tun, als sei ich ein Experte für UI-Muster: Wenn ich die Bedenken angesprochen habe, nehme ich an, dass dies die Art und Weise ist, wie Sie arbeiten möchten, und gehen Sie auf die Frage selbst ein:)

Ich persönlich finde Joshs vorgeschriebenes Muster 1 für einfache Szenarien zu komplex - Ihr Ansatz ist in Ordnung, mit nur einer Änderung: Machen Sie Ihre Klasse versiegelt. Wenn Sie die Klasse nicht versiegeln möchten, sollten Sie die Option Dispose(bool) wählen (aber ohne den Finalizer), da die Unterklassen möglicherweise auch über Dinge verfügen müssen und möglicherweise einen Finalizer benötigen. Ohne die Möglichkeit eines abgeleiteten Typs ist das Leben einfacher (wie so oft).

Sie müssen nichts mit anderen Mitgliedern tun, nur weil Sie jetzt IDiposable aus diesem einen Grund implementieren.

Also, müssen Sie etwas weiter von dieser Klasse ableiten?

1 Ich verstehe, dass dies das empfohlene Standardmuster ist, obwohl ich Ihnen empfehlen würde, den Rat von Joe Duffy et al für noch mehr Details - es kann alles sehr kompliziert machen.

    
Jon Skeet 13.01.2010, 07:20
quelle
5

Persönlich würde ich vermeiden, das Ereignis im Konstruktor ein- und auszuhängen und es zu entfernen. Stattdessen würde ich den View get / set Accessoren Code hinzufügen und sie dort hinzufügen. Aber wenn der Presenter entsorgt wird, während eine View angeschlossen ist, würde ich nicht versuchen, das zu bereinigen. Sie können die Ansicht explizit vom Moderator trennen, wenn Sie explizit gelöst werden müssen.

Nachdem ich das gesagt habe, hier ist, was ich über IDisposable weiß.

Der empfohlene Ansatz zum Implementieren von IDisposable besteht darin, eine geschützte Dispose (bool) -Methode zu verwenden Aktion. Der Grund ist, dass Sie zwischen einer expliziten Entsorgung und einer Entsorgung, die durch Finalisierung verursacht wird, unterscheiden möchten (Garbage Collection.)

Wenn Sie aufgrund eines expliziten Dispose () -Aufrufs entsorgt werden, ist es in Ordnung, verwaltete Objekte zu berühren. Von Ihnen wird erwartet, dass Sie alles, was Sie erstellt haben, ebenfalls entsorgen müssen. Also tust du das nur, wenn disposing = true ist.

Aber wenn jemand (Sie) vergisst, Dispose aufzurufen und der Finalizer aufgerufen wird, werden Sie nach der Garbage-Collection entsorgt (disposing = false) und Sie möchten keine verwalteten Objekte anfassen, da diese möglicherweise bereits finalisiert sind. Das einzige, was Sie in diesem Fall frei machen müssen, sind nicht verwaltete Ressourcen wie Win32-Handles und so.

Schließlich, wenn Dispose () explizit aufgerufen wird, werden Sie feststellen, dass ich GC.SupressFinalize (this) aufgerufen habe, was ein Leistungshinweis für den Garbage Collector ist. Es informiert Sie darüber, dass das Objekt nicht abgeschlossen werden muss, wenn es erfasst wird. Finalisierung ist nicht billig.

%Vor%     
Josh 13.01.2010 06:44
quelle

Tags und Links