In C # wird die using
Anweisung verwendet, um die Ressourcen deterministisch zu entsorgen, ohne auf den Garbage Collector zu warten. Zum Beispiel kann es verwendet werden, um:
Entsorgen Sie SQL-Befehle oder -Verbindungen.
Schließen Sie Streams und geben Sie die zugrunde liegende Quelle wie eine Datei frei.
Kostenlose GDI + Elemente,
etc.
Mir ist aufgefallen, dass dies using
immer häufiger in Fällen verwendet wird, in denen nichts zu entsorgen ist, der Anrufer jedoch nur bequemer einen using
Block als zwei separate Befehle schreiben kann .
Beispiele:
MiniProfiler , geschrieben vom Stack Overflow-Team,
using
bezeichnet Blöcke im Profil:using (profiler.Step("Name goes here")) { this.DoSomethingUseful(i - 1); }
Ein alternativer Ansatz wäre, zwei Blöcke zu haben:
var p = profiler.Start("Name goes here"); this.DoSomethingUseful(i - 1); profiler.Stop(p);
Ein anderer Ansatz wäre die Verwendung von Aktionen:
profiler.Step("Name goes here", () => this.DoSomethingUseful(i - 1));
ASP.NET MVC hat auch folgende
using
Formulare ausgewählt:<% using (Html.BeginForm()) { %> <label for="firstName">Name:</label> <%= Html.TextBox("name")%> <input type="submit" value="Save" /> <% } %>
Ist eine solche Verwendung angemessen? Wie kann man das rechtfertigen, da es mehrere Nachteile gibt:
Anfänger wären verloren, da eine solche Verwendung nicht der entspricht, die in Büchern und Sprachspezifikationen erklärt wird.
Der Code sollte ausdrucksstark sein. Hier leidet die Ausdruckskraft, da die angemessene Verwendung von darin
using
besteht, zu zeigen, dass sich dahinter eine Ressource wie ein Stream, eine Netzwerkverbindung oder eine Datenbank befindet, die freigegeben werden sollte, ohne auf den Garbage Collector zu warten.
quelle
using
: Die letztere Anweisung (z. B.profiler.Stop(p)
) kann angesichts von Ausnahmen und Kontrollabläufen nicht garantiert ausgeführt werden.Antworten:
Ihre letzte Aussage - dass "die angemessene Verwendung der Verwendung darin besteht, zu zeigen, dass sich dahinter eine Ressource wie ein Stream, eine Netzwerkverbindung oder eine Datenbank befindet, die freigegeben werden sollte, ohne auf den Garbage Collector zu warten", ist falsch, und der Grund dafür ist Weitere Informationen finden Sie in der Dokumentation zur IDisposable-Schnittstelle: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Wenn Ihre Klasse also nicht verwaltete Ressourcen verwendet, spielt es keine Rolle, wann Sie GC durchführen möchten oder nicht - es hat überhaupt nichts mit GC zu tun, da nicht verwaltete Ressourcen nicht GC-fähig sind ( https: // stackoverflow). com / Fragen / 3607213 / what-is-gemeint-by-Managed-vs-unmanaged-Ressourcen-in-net ).
So ist der Zweck der „Verwendung“ nicht auf GC zu vermeiden , ist warten, dann ist es eine Freisetzung von diesen nicht verwalteten Ressourcen zu zwingen , jetzt , bevor die Klasseninstanz Gültigkeitsbereich verlässt und Finalisierung der es heißt. Dies ist aus Gründen wichtig, die offensichtlich sein sollten: Eine nicht verwaltete Ressource kann Abhängigkeiten von anderen nicht verwalteten Ressourcen aufweisen, und wenn sie in der falschen Reihenfolge entsorgt (oder finalisiert) werden, können schlimme Dinge passieren.
Wenn die im using-Block instanziierte Klasse nicht verwaltete Ressourcen verwendet, lautet die Antwort "Ja" - dies ist angemessen.
Beachten Sie, dass IDisposable nicht normativ ist darüber sind nur für die Freigabe von nicht verwalteten Ressourcen, aber - nur , dass dies es ist primärer Zweck. Es kann vorkommen , dass der Autor der Klasse eine Aktion hat, die er zu einem bestimmten Zeitpunkt erzwingen möchte, und die Implementierung von IDisposable kann eine Möglichkeit sein, dies zu erreichen, aber ob dies eine elegante Lösung ist oder nicht, kann dies nur von Fall zu Fall beantwortet werden.
Unabhängig davon impliziert die Verwendung von "using", dass die Klasse IDisposable implementiert, sodass die Ausdruckskraft des Codes nicht verletzt wird. es macht ziemlich klar, was tatsächlich los ist.
quelle
Die Verwendung von
using
impliziert das Vorhandensein einerDispose()
Methode. Andere Programmierer gehen davon aus, dass eine solche Methode für das Objekt vorhanden ist. Wenn ein Objekt nicht wegwerfbar ist, sollten Sie es daher nicht verwendenusing
.Code Klarheit ist König. Lassen Sie das Objekt entweder weg
using
oder implementieren Sie esIDisposable
für das Objekt.MiniProfiler scheint
using
als Mechanismus zu dienen, um den zu profilierenden Code " einzäunen ". Dies hat einen gewissen Wert. Vermutlich ruft MiniProfiler entwederDispose()
auf, um einen Timer zu stoppen, oder der Timer wird gestoppt, wenn das MiniProfiler-Objekt den Gültigkeitsbereich verlässt.Im Allgemeinen würden Sie aufrufen,
using
wenn eine Art Finalisierung automatisch erfolgen muss. In der Dokumentation fürhtml.BeginForm
heißt es, dass bei Verwendung der Methode in einerusing
Anweisung das schließende</form>
Tag am Ende desusing
Blocks gerendert wird.Das bedeutet nicht unbedingt, dass es immer noch kein Missbrauch ist.
quelle
IDisposable
/Dispose()
obwohl es nichts zu entsorgen hat, wie es OP beschreibt?Dispose
ist erforderlichusing
, um überhaupt Sinn zu machen (unabhängig davon, ob es angemessen ist). Die Beispiele von OP werden alle implementiertDispose
, nicht wahr? Und IIUC, die Frage ist, ob es richtig ist, dass diese KlassenDispose
anstelle einer anderen Methode (wieStop()
bei MiniProfiler) verwenden.using
ist fehler- und ausnahmesicher. Es stellt sicherDispose()
, dass unabhängig von Fehlern, die der Programmierer macht, aufgerufen wird. Es beeinträchtigt nicht das Abfangen oder Behandeln von Ausnahmen, aber dieDispose()
Methode wird rekursiv im Stapel ausgeführt, wenn eine Ausnahme ausgelöst wird.Objekte, die implementiert werden,
IDispose
aber nichts zu entsorgen haben, wenn sie fertig sind. Sind bestenfalls zukunftssicher für ihr Design. Damit Sie Ihren Quellcode nicht umgestalten müssen, müssen sie in Zukunft über etwas verfügen.quelle