Warum structs nicht haben Destruktoren?
Was ist die beste Antwort bei interview auf eine solche Frage, die Sie denken?
Ich denke, ich habe nicht eine Kopie von diesem hier, wenn es einen gibt bitte verlinken.
InformationsquelleAutor der Frage Valentin Kuzub | 2011-11-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Andere Art der Betrachtung dieser - anstatt nur unter Angabe der spec, die besagt, dass Strukturen nicht/keine Destruktoren - überlegen, was passieren würde, wenn die Skillung wurde so geändert, dass Sie Tat - oder vielmehr, lassen Sie uns die Frage stellen: können wir erraten warum hat die Sprache, die Designer entscheiden, nicht zu erlauben, Strukturen zu haben, die 'Zerstörer' in den ersten Platz?
(Don ' T get hung up auf das Wort 'destructor', wir sind im Grunde reden über eine Magische Methode auf Strukturen, die wird automatisch aufgerufen, wenn die variable geht out of scope. In anderen Worten, einer Sprache, die Funktion, die Analog zur C++ - Destruktoren.)
Das erste, was zu erkennen ist, dass wir kümmern uns nicht um das freigeben von Speicher. Ob das Objekt auf dem stack oder auf dem heap (zB. ein struct in einer Klasse), die Speicher kümmern und die eine oder andere Weise früher oder später; entweder, indem Sie spontan aus dem Stapel oder durch gesammelt werden. Der wahre Grund für etwas, dass Destruktor, so wie in den ersten Platz ist für die Verwaltung externe Ressourcen - Dinge wie Datei-handles, Fenster, Griffe, oder andere Dinge, die brauchen eine Besondere Behandlung zu bekommen, bis Sie gereinigt, dass die CLR selbst nicht kennen.
Nun soll Ihnen ermöglichen, eine Struktur zu haben, einen Destruktor, können dies tun, Aufräumen. Fein. Bis Sie erkennen, dass, wenn structs als Parameter übergeben werden, bekommen Sie durch Wert übergeben: Sie werden kopiert. Jetzt hast du zwei Strukturen mit der gleichen internen Felder, und Sie sind beide gehen, um zu versuchen zu bereinigen das gleiche Objekt. Man passiert zuerst, und so code, mit dem anderen hinterher, scheitern geheimnisvoll... und dann seine eigene cleanup schlägt fehl (hoffentlich! - Schlimmste Fall ist, könnte es gelingen, Aufräumen einige andere zufällige Ressource - dies kann in Situationen, in denen die handle-Werte wiederverwendet werden, zum Beispiel.)
Sie könnten möglicherweise machen ein besonderer Fall für Strukturen, die Parameter so, dass Ihre "Destruktoren " don' T run (aber Vorsicht - von nun an müssen Sie daran denken, dass wenn Sie eine Funktion aufrufen, es ist immer die äußere, "besitzt" die eigentliche Ressource, die - jetzt so einige Strukturen sind subtil anders auf andere...) - aber dann haben Sie immer noch dieses problem mit regelmäßigen struct-Variablen, denen man zugeordnet werden können, zum anderen, eine Kopie zu erstellen.
Könnte man vielleicht umgehen Sie dies, indem Sie einen speziellen Mechanismus zur Zuordnung von Operationen, die irgendwie ermöglicht die neue Struktur zu verhandeln Besitz der zugrunde liegenden Ressource mit der neuen copy - vielleicht haben Sie es teilen oder die übertragung von Eigenverantwortung geradezu von der alten auf die neue - aber jetzt haben Sie im wesentlichen fuhren in C++-land, wo Sie brauchen, copy-Konstruktoren, Zuweisungsoperatoren, und Hinzugefügt haben eine Reihe von Feinheiten warten auf Falle den unwissenden Anfänger-Programmierer. Und im Hinterkopf behalten, dass der ganze Punkt von C# ist zu vermeiden, in der Art von C++-Stil, Komplexität so weit wie möglich.
Und, nur um die Dinge ein bisschen mehr verwirrend, als einer der anderen Antworten hingewiesen, Strukturen nicht nur existieren, die als lokale Objekte. Mit den einheimischen, Rahmen ist schön und gut definiert; aber Strukturen können auch Mitglieder einer Klasse Objekt. Wann sollte die 'Destruktor' genannt, bekommen in diesem Fall? Sicher, Sie können es tun, wenn die container-Klasse ist abgeschlossen; aber jetzt haben Sie einen Mechanismus, der verhält sich sehr unterschiedlich, je nachdem, wo der struct Leben: wenn die Struktur ist ein lokal, es wird ausgelöst, unmittelbar am Ende des Bereichs; wenn das struct innerhalb einer Klasse wird ausgelöst, träge... Also wenn Sie wirklich sicherstellen, dass einige Ressourcen in Ihren Strukturen gereinigt ist bis zu einem bestimmten Zeitpunkt, und wenn Ihre Struktur könnte am Ende als Mitglied einer Klasse, Sie würden wahrscheinlich brauchen etwas, das explizite wie IDisposable/using() jedenfalls, um sicherzustellen, Sie haben Ihre Grundlagen abgedeckt.
So, ich kann zwar nicht behaupten, sprechen die Sprache der Designer, damit kann ich eine ziemlich gute Vermutung, dass ein Grund, Sie beschlossen, nicht zu schließen solche ein feature ist, denn es wäre ein Chaos, und Sie wollte zu halten, C# relativ einfach.
InformationsquelleAutor der Antwort BrendanMcK
Vom Jon Jagger:
"Ein struct kann ein Destruktor. Ein Destruktor ist nur ein überschreiben der
object.Finalize
im Unglück, und Strukturen, Wert-Typen, unterliegen nicht der garbage collection."InformationsquelleAutor der Antwort Cameron Skinner
Jedem anderen Objekt als arrays und strings gespeichert ist, auf dem heap in der gleichen Weise: eine Kopfzeile, die Informationen über das "Objekt-bezogene" Eigenschaften (Typ, ob es von jedem aktiven monitor sperren, ob es eine nicht-unterdrückte
Finalize
- Methode, etc.), und seine Daten (d.h. die Inhalte aller Typ-Instanz-Felder (public, private und protected vermischt, mit base-class-Felder erscheinen vor abgeleitet-Typ-Felder). Da jede heap-Objekt hat einen header, das system kann eine Referenz auf ein beliebiges Objekt und wissen, was es ist, und was der garbage-collector soll zu tun. Wenn das system eine Liste aller Objekte, die erstellt wurden und haben einenFinalize
Methode ist, können Sie prüfen jedes Objekt in der Liste sehen, wenn IhrFinalize
Methode ist aufgehoben, und handeln Sie entsprechend.Structs gespeichert sind, ohne Kopf; eine Struktur, die wie
Point
mit zwei integer-Felder ist einfach gespeichert, als zwei Ganzzahlen. Während es möglich ist, einref
um eine Struktur, die (wie eine Sache, die erstellt wird, wenn ein struct übergebenref
parameter), wird der code, der verwendet, derref
hat zu wissen, welche Art von Struktur dieref
Punkte, da weder dieref
noch die struct selbst hält diese Informationen. Weitere, heap-Objekte können nur erstellt werden, indem der garbage-collector, die garantieren, dass jedes Objekt, das erstellt wird immer bestehen, bis die nächste GC-Zyklus. Durch Kontrast, user-code zu erstellen und zerstören Strukturen, die von sich selbst (oft auf dem stack); if code erstellt eine Struktur, die zusammen mit einemref
es, und das reichtref
es zu einer aufgerufenen routine, es gibt keine Möglichkeit, code kann zur Zerstörung der Struktur (oder überhaupt etwas tun, für diese Angelegenheit), bis die aufgerufene routine gibt, so dass die Struktur wird garantiert, um zu existieren, zumindest bis die aufgerufene routine beendet. Auf der anderen Seite, wenn die aufgerufene routine beendet wird, dieref
es gegeben wurde, sollte davon ausgegangen werden ungültig, da der Anrufer wäre frei, das zu zerstören, struct jederzeit danach.InformationsquelleAutor der Antwort supercat
Weil per definition Destruktoren werden verwendet, um zu zerstören, Instanzen von Klassen und structs sind value-Typen.
Ref: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
Durch Microsoft ' s eigenen Worten:
"Destructors are used to destruct instances of classes."
so ist es ein wenig albern, zu Fragen, "Warum können Sie nicht verwenden, ein Destruktor (etwas, das nicht ein Klasse)?" ^^InformationsquelleAutor der Antwort aevanko