Sollte GC.SuppressFinalize auf Objekte aufgerufen werden, die nicht über einen Finalizer haben?
Frage
Aus irgendeinem Grund FXCop scheint zu denken, ich anrufen sollte GC.SuppressFinalize in entsorgen, und zwar unabhängig davon, ob ich einen Finalizer haben oder nicht.
Bin ich etwas fehlt? Gibt es einen Grund GC.SuppressFinalize auf Objekte zu nennen, die nicht Finalizerthread definiert haben?
Lösung
Es gibt immer eine Finalizerthread in IL - System.Object.Finalize () gibt es in jeder Klasse, so dass, wenn Sie eine benutzerdefinierte Klasse machen, hat es eine Finalizerthread Sie unterdrücken wollen. Davon abgesehen, nicht alle Objekte auf dem Finalisierungsschlange setzen, so dass Sie nur techncially sollten Finalisierung müssen, zu unterdrücken, wenn Sie Ihre eigene Finalizerthread implementieren.
Wenn Sie IDisposable
sind die Umsetzung von nicht verwalteten Ressourcen zu wickeln, sollten Sie einen Finalizer umfassen, und Sie sollten diese nicht ausgeführt werden, da in der Theorie sind Sie die Bereinigung bereits tun, wenn Dispose
aufgerufen wird.
Andere Tipps
Es gibt keine Notwendigkeit GC.SuppressFinalize(this)
in Entsorgen Sie anrufen, es sei denn:
- Sie sind die Basisklasse, die für das Überschreiben virtuelle Entsorgen Methoden bestimmt implementiert (wieder, es ist nicht Ihre Verantwortung sein könnte auch hier, aber Sie könnten es in diesem Fall tun wollen)
- Sie haben einen Finalizer selbst. Technisch hat jede Klasse in .NET einen Finalizer, aber wenn die einzige Finalizerthread vorhanden derjenige in
Object
ist, dann wird das Objekt nicht brauchen Finalisierung betrachtet und nicht auf der Finalisierungsliste auf GC setzen
Ich würde sagen, Sie unter der Annahme, haben keine der oben genannten Fälle, dass Sie diese Nachricht ignorieren.
Alle Objekte haben eine Finalizer-Methode, auch wenn Sie nicht durch die Verwendung eines c # destructor umgesetzt haben (die durch die GC nicht tatsächlich garantiert wird aufgerufen werden). Es ist nur gute Praxis, den Anruf zu unterdrücken, wenn Sie IDisposable implementiert haben, denn das bedeutet, dass Sie die Finalisierung explictly auszuführen haben.
Ich sehe keine Notwendigkeit SuppressFinalize () aufzurufen, wenn es keine Finalizerthread definiert. Wenn Sie defensiv sein wollen, dann kann es gut sein, einen Finalizer zu haben sowie Dispose (), so müssen Sie nicht auf Kunden angewiesen immer Dispose () aufrufen. Dann werden Sie keine Ressourcen lecken, wenn sie vergessen.