Betrachten Sie den folgenden Code ein:Warum entsorgt ein Stream, wenn sein Brenner entsorgt wird?
using (var ms = new MemoryStream())
{
using(var writer = BinaryWriter(ms))
{
writer.Write(/*something*/);
writer.Flush();
}
Assert.That(ms.Length > 0); // Throws ObjectDisposedException
}
Auf der einen Seite, ein Einweg-Objekt sollte es die Ressourcen verfügen; Ich bekomme das, aber auf der anderen Seite, das Objekt nicht erstellt und besitzt diese Ressource nicht, es wurde zur Verfügung gestellt -> Calling Code sollte die Verantwortung dafür übernehmen ... nein?
Ich kann nicht an andere Situationen wie diese denken, aber ist es ein einheitliches Muster im Rahmen für jede Klasse, die Einwegobjekte erhält, um sie auf eigene Weise zu entsorgen?
Objekte sollten nicht über Dinge verfügen, die sie nicht besitzen *. Es ist möglich, Eigentum an anderen Objekten zu erwerben, als diese direkt zu instantiieren (am häufigsten durch Aufruf einer Factory-Methode). Da Factory-Methoden in der Regel nur ein einzelnes Objekt zurückgeben, müssen alle von der Methode erfassten Ressourcen Eigentum dieses Objekts sein. Wenn ein "StreamWriter" den Besitz eines übergebenen Streams übernimmt, ist es möglich, dass eine Factory-Methode legitim einen Stream erstellt und einen "StreamWriter" zurückgibt, der ihn einkapselt. – supercat
@supercat eh nein. Ich stimme dir zu "Objekte sollten Dinge, die sie nicht besitzen, nicht entsorgen". Das ist die richtige Art, das zu sagen. Aber nicht in diesem Fall. Wenn Sie die StreamWriter-Klasse selbst entwerfen, haben Sie keine Ahnung, wie der Aufrufer mit dem Stream umgehen soll, und auch nicht. Berücksichtigen Sie Fälle, in denen ein Stream in mehreren Lesern verwendet wird. Dann müssen Sie den StreamReader bedingt mit einer using-Anweisung umbrechen, je nachdem, ob Sie ihn löschen möchten. IDisposable sollte mithilfe der Anweisung warpped werden. Keine Fragen gefragt. –
Die richtige Vorgehensweise ist, dass der Konstruktor von 'StreamReader' /' StreamWriter' dem Aufrufer erlaubt anzugeben, ob der Besitz übertragen wird (in späteren Versionen von .NET). Andernfalls bedenken Sie, wie man eine Methode schreiben würde, die asynchron Daten abspielen soll, die von einem 'StreamReader' abgerufen werden. Der Code, der den Ton abspielt, kann nichts über den zugrunde liegenden Stream wissen, und der Code, der den "StreamReader" erzeugt, hat möglicherweise keine Ahnung, wann der Wiedergabecode damit gemacht wird. In dem allgemeinen Fall, in dem der Stream nur zum Zwecke der Audiowiedergabe geöffnet wurde ... – supercat