Warum entsorgt Objekt keine Ausnahme auslösen, die auf mit es nach zu entsorgen?
Ist es legal aufrufen einer Methode entsorgt Objekt? Wenn ja, warum?
In der folgenden demo-Programm habe ich eine Einweg-Klasse A
(die implementiert IDisposable
- Schnittstelle).Soweit ich weiß, wenn ich den pass weggeschmissen, um using()
konstruieren, dann Dispose()
Methode aufgerufen wird, wird automatisch nach der schließenden Klammer:
A a = new A();
using (a)
{
//...
}//<--------- a.Dispose() gets called here!
//here the object is supposed to be disposed,
//and shouldn't be used, as far as I understand.
Wenn das richtig ist, dann bitte erklären Sie die Ausgabe dieses Programms:
public class A : IDisposable
{
int i = 100;
public void Dispose()
{
Console.WriteLine("Dispose() called");
}
public void f()
{
Console.WriteLine("{0}", i); i *= 2;
}
}
public class Test
{
public static void Main()
{
A a = new A();
Console.WriteLine("Before using()");
a.f();
using ( a)
{
Console.WriteLine("Inside using()");
a.f();
}
Console.WriteLine("After using()");
a.f();
}
}
Ausgang (ideone):
Before using()
100
Inside using()
200
Dispose() called
After using()
400
Wie kann ich call f()
auf das veräusserte Objekt a
? Ist dies erlaubt? Wenn ja, dann warum? Wenn Nein, warum dann das obige Programm nicht geben exception zur Laufzeit?
Ich weiß, dass das beliebte Konstrukt mit using
ist diese:
using (A a = new A())
{
//working with a
}
Aber ich bin einfach zu Experimentieren, das ist, warum ich schrieb es anders.
Was du also sagst ist : ich schrieb ein Programm, das nicht implementieren, der Vertrag von Einweg-Objekte, und wenn ich es laufen lasse, es nicht zu implementieren, der Vertrag von Einweg-Objekte. Sie sind verantwortlich für die Umsetzung, die Verhalten. Sie haben es nicht getan. Gehen, tun Sie es.
InformationsquelleAutor Nawaz | 2011-09-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Entsorgt, bedeutet nicht verschwunden. Entsorgen bedeutet nur, dass alle nicht verwalteten Ressource (wie eine Datei, Verbindung jeglicher Art, ...) wurde veröffentlicht. Während dies in der Regel bedeutet, dass das Objekt nicht nützliche Funktionalität, möglicherweise gibt es noch Methoden, die nicht davon abhängen, dass nicht verwaltete Ressource und immer noch funktionieren wie gewohnt.
Die Entsorgung Mechanismus existieren .net (und inheritly, C#.net) ist ein garbage Collection-Umgebung, das heißt, Sie sind nicht verantwortlich für die Speicherverwaltung. Aber der garbage collector kann nicht entscheiden, ob eine nicht verwaltete Ressource wurde unter Verwendung beendet werden, so müssen Sie dies selbst tun.
Wenn Sie möchten-Methoden eine exception werfen, nachdem das Objekt wurde diposed, benötigen Sie einen boolean zu erfassen, die dispose-status, und sobald das Objekt entsorgt wird, werfen Sie die Ausnahme:
Offensichtlich. Aber das ist der Fall mit einer kritischen Verhalten, bin ich davon ausgegangen das der Idealfall.
Aber nach Dispose-Muster entsorgen bedeutet sowohl für verwaltete und nicht verwaltete Ressourcen freigegeben werden, wenn Sie aufgerufen vom client extern. In diesem Fall erwarte ich keine Methode funktioniert. richtig?
InformationsquelleAutor Femaref
Die exception wird nicht geworfen, weil Sie noch nicht entwickelt, die Methoden zu werfen
ObjectDisposedException
nachDispose
aufgerufen wurde.Der clr nicht automatisch wissen, dass es werfen sollte
ObjectDisposedException
einmal Dispose aufgerufen wird. Es ist Ihre Verantwortung, werfe eine Ausnahme, wenn Dispose freigegeben hat alle Ressourcen, die benötigt werden für eine erfolgreiche Ausführung Ihrer Methoden.InformationsquelleAutor Giorgi
Einem typischen Dispose () - Implementierung, die nur Aufrufe von Dispose() auf beliebige Objekte, die Sie speichert in den Feldern, die sind Einweg. Was wiederum die Freigabe nicht verwalteter Ressourcen. Wenn Sie IDisposable implementieren und nicht wirklich etwas tun, wie du getan hast in deinem snippet, dann den Objekt-Zustand nicht ändern. Da kann nichts schief gehen. Nicht verwechseln Verfügung mit Abschluss.
InformationsquelleAutor Hans Passant
Zweck der IDisposable ist es, ein Objekt zu fixieren, der Staat von außerhalb der Personen, die für seinen Vorteil, in einem Zustand, der weniger als ideal für andere Zwecke verwendet werden. Zum Beispiel, Io.- Ports.SerialPort-Objekt könnte sich geändert haben, den Zustand von einem seriellen port "verfügbar, für jede Anwendung, die Sie will" , "kann nur von einer bestimmten Io.- Ports.SerialPort-Objekt"; der primäre Zweck der SerialPort.Entsorgen ist die Wiederherstellung der Status des com-port "für jede Anwendung".
Natürlich erst einmal ein Objekt, das IDisposable implementiert wurde reset Entitäten, hatte die Aufrechterhaltung eines bestimmten Status, für seinen Vorteil, es wird nicht mehr den nutzen von diesen Personen gepflegt Zustand. Zum Beispiel, wenn der Status des com-port eingestellt wurde, um "für jede Anwendung", die Datenströme, mit dem er verbunden gewesen, können nicht mehr verwendet werden, um Daten senden und empfangen. Wenn ein Objekt konnte normal funktionieren, ohne externe Entitäten, die in einen speziellen Zustand für sein nutzen ist, gibt es keinen Grund zu verlassen, außerhalb von Personen in einem besonderen Zustand in den ersten Platz.
Generell nach IDisposable.Entsorgen Sie genannt wurde, auf ein Objekt, das Objekt sollte nicht erwartet werden, um in der Lage sein, viel tun. Der Versuch, mit den meisten Methoden auf, ein solches Objekt würde bedeuten, einen Fehler; wenn eine Methode nicht zuzumuten ist, zu arbeiten, den richtigen Weg zu zeigen, der über ObjectDisposedException.
Microsoft deutet darauf hin, dass fast alle Methoden auf ein Objekt, das IDisposable implementiert werfen sollte ObjectDisposedException, wenn Sie auf ein Objekt, das veräußert wurde. Ich würde vorschlagen, dass eine solche Beratung ist overbroad. Es ist oft sehr nützlich für die Geräte aussetzen, Methoden oder Eigenschaften, um herauszufinden, was passiert ist, während das Objekt noch am Leben war. Obwohl man geben könnte, eine Kommunikations-Klasse eine Close-Methode, sowie eine Dispose-Methode, und erlaubt nur eine Abfrage, die Dinge wie NumberOfPacketsExchanged nach einer engen, aber nicht nach einer Entsorgen, aber das scheint zu kompliziert. Lesen Eigenschaften der Dinge, die passiert sind, bevor ein Objekt Entsorgt wurde, scheint eine ganz einfache Muster.
InformationsquelleAutor supercat
Einen Entsorger in C# ist nicht das gleiche wie ein Destruktor in C++. Ein Entsorger wird verwendet, um den release geschafft (oder unmanaged) Ressourcen, während das Objekt immer noch gültig.
Ausnahmen geworfen werden, abhängig von der Implementierung der Klasse. Wenn
f()
erfordert nicht die Verwendung Ihrer bereits entsorgt Objekte, dann muss nicht unbedingt eine Ausnahme.InformationsquelleAutor Marlon
Aufrufen
Dispose()
nicht Referenz auf das Objektnull
, und Ihre benutzerdefinierte Einweg-Klasse enthält keine Logik, die eine exception werfen, wenn seine Funktionen zugegriffen werden, nachdemDispose()
genannt wurde, so ist es natürlich legal.In der realen Welt
Dispose()
releases nicht verwalteten Ressourcen und diese Ressourcen nicht mehr verfügbar, danach und/oder vor der Klasse Autor hat es werfenObjectDisposedException
wenn Sie versuchen, um das Objekt nach dem AufrufDispose()
. In der Regel ein class-level boolean würde auf true gesetzt werden, die innerhalb des Körpers desDispose()
und diesen Wert überprüft der anderen Mitglieder der Klasse, bevor Sie tun, jede Arbeit, mit der Ausnahme, die geworfen wird, wenn der bool true ist.InformationsquelleAutor Stephen Kennedy