Nachdem ich viele Artikel von Idisposable gelesen hatte, war ich verwirrt darüber. Alle Artikel erklären, was es ist und wie es umgesetzt wird. Ich möchte verstehen, was wir vermissen werden, wenn wir es nicht haben. Es ist eine Schnittstelle mit einer Methode Dispose () darin. Nehmen wir ein Beispiel Häufig wird die Verwendung von "dispose" als eine Datenbankverbindung
bezeichnetDer Code wäre wie
%Vor%Obwohl dispose implementiert ist, aber innerhalb der dispose-Methode, wird die dispose-Eigenschaft von databaseconnection verwendet, um die Verbindung freizugeben (this.databaseConnection.Dispose ();)
Meine Frage ist Warum müssen wir IDisposable in diesem Fall implementieren? Wir können dies direkt aufrufen. DatabaseConnection.Dispose () und die Verbindung freigeben. Warum zu implementieren, wenn intern auch die Dispose-Eigenschaft des Objekts aufgerufen wird. Alternativ zum Ansatz von Idisposable können wir eine Methode Release implementieren, um den Speicher freizugeben.
%Vor%Was ist der Unterschied zwischen den beiden Ansätzen? Brauchen wir wirklich Entsorgen? Ich freue mich auf eine konkrete Erklärung.
Sie haben recht, wenn Sie Ihre Release-Methode verwenden, erhalten Sie genau den gleichen Effekt, vorausgesetzt, Sie erinnern sich immer daran, sie aufzurufen.
Der Grund, warum Sie Dispose
/ IDisposable
für diese Art von Dingen verwenden sollten, ist Konsistenz. Alle .NET-Entwickler werden über das IDisposable-Muster Bescheid wissen, und eine Klasse, die IDisposable ist, gibt an, dass Sie darüber verfügen sollten, und tun Sie das mit der Dispose-Methode. Mit anderen Worten sagt die Verwendung des IDisposable-Musters einem anderen Entwickler sofort, dass er die von der Klasse gehaltenen Ressourcen freigeben sollte, und er sollte dies tun, indem er die Methode Dispose
aufruft.
Ein weiterer Vorteil der Implementierung von IDisposable
ist der using-Block, der für jede IDisposable-Klasse funktioniert:
Wenn Sie den obigen Code verwenden, wird t
als Dispose()
ed am Ende des Blocks using
angezeigt. Es ist syntaktischer Zucker für einen try
... finally
-Block, aber es neigt dazu, diese Art von Code prägnanter und einfacher zu lesen und zu schreiben.
Release()
korrekt funktioniert (nicht, aber das ist eine andere Sache), müssten die Leute etwas darüber lernen und etwas anderes mit einer anderen Klasse lernen usw. Ihr Release()
konnte niemals programmatisch gefunden werden. Es ist möglich, programatically Dispose()
aufzurufen, wenn zutreffend mit:
if (obj ist IDisposable) ((IDisposable) obj) .Dispose ();
Obwohl nicht oft getan, wenn es fertig ist, ist es wichtig.
Manchmal ist es nützlich, eine Methode wie Ihre Release()
zu haben, wenn es möglich ist, dass jemand sie während der Objektbenutzung aufrufen möchte. Ein Beispiel dafür ist Close()
auf Stream
. Beachten Sie jedoch, dass Stream.Dispose()
weiterhin vorhanden ist und in Close()
aufruft.
IDisposable ist es wert, implementiert zu werden, vor allem weil es in C # idomatic ist. Jeder weiß, was IDisposable macht und wie man mit einem Objekt umgeht, das IDisposable implementiert. Wenn Sie Ressourcen freigeben, die etwas anderes als IDisposable.Dispose () verwenden, weichen Sie vom allgemein verständlichen Idiom ab.
Dies bedeutet, dass ein Betreuer nicht die Details Ihrer Klasse kennen muss, um undichte Ressourcen zu vermeiden. Dies kann sogar in 6 Monaten der Fall sein, wenn Sie das meiste vergessen haben, was Sie mit diesem Code getan haben! Alles, was Sie wissen müssen, ist, dass es IDisposable implementiert, was eine allgemein verstandene Bedeutung hat.
Denken Sie daran, dass IDisposable meist ein Signal an einen Entwickler ist: "Hey, ich bin eine Klasse, die Verweise auf nicht verwaltete Ressourcen enthält. Sie sollten wahrscheinlich nicht auf den Müllsammler warten, um mich zu säubern." Beachten Sie, dass dies indirekt über Komposition erfolgen kann (eine Klasse, die IDisposable implementiert, da sie über private Member verfügt, die IDisposable implementieren). Wenn ein anständiger C # -Entwickler eine Klasse erkennt, die IDisposable implementiert, sollten sie sofort denken: "Dieses Objekt ist speziell und muss aufgeräumt werden, wenn ich damit fertig bin." Es gibt nichts, was Sie davon abhält, eine Release () -Methode zu schreiben; Es bedeutet nur, dass Sie eher versehentlich Ressourcen verlieren, weil Sie nicht das idiomatische Muster verwenden.
Verwaltete Objekte werden automatisch von der Garbage Collection an einem nichtdeterministischen Punkt in der Zukunft entsorgt. Wenn Sie jedoch mit Objekten arbeiten, die nicht verwaltete Ressourcen enthalten (nicht unter der Kontrolle der CLR / Garbage Collection), sollte IDisposable implementiert werden, um eine konsistente und deterministische Methode zur Rückgabe dieser Ressourcen an das Betriebssystem bereitzustellen.
Die Schnittstelle bietet nur dann einen echten Vorteil, wenn das Objekt im Kontext eines using () {...} Blocks verwendet wird. Ein solcher Block weist die CLR an, die Dispose-Methode aufzurufen, wenn sie die schließende Klammer des Blocks trifft. Unabhängig davon, was in diesem Block geschieht (abgesehen von einem katastrophalen Systemausfall), wird Ihre Dispose-Methode garantiert aufgerufen und Ihre nicht verwalteten Ressourcen freigegeben.
Wenn Sie beispielsweise in dem von Ihnen bereitgestellten Code eine Ausnahme ausgelöst haben, wurde Ihre Release () -Methode möglicherweise nie aufgerufen, sodass die Verbindung möglicherweise geöffnet bleibt. Wenn Sie jedoch mit einem Disposable-Objekt innerhalb eines using-Blocks arbeiten und die Ausnahme ausgelöst wird, springt die CLR ein und ruft Ihre Dispose-Methode auf, bevor sie die Ausnahme auslöst.
Tags und Links c# idisposable