Freigeben über


Auswählen zwischen Klasse und Struktur

Hinweis

Dieser Inhalt wird mit Genehmigung von Pearson Education, Inc. aus Framework Design Guidelines: Konventionen, Idiome und Muster für wiederverwendbare .NET-Bibliotheken, 2. Auflage nachgedruckt. Diese Ausgabe wurde 2008 veröffentlicht, und das Buch wurde seitdem in der dritten Ausgabe vollständig überarbeitet. Einige der Informationen auf dieser Seite sind möglicherweise veraltet.

Eine der grundlegenden Entwurfsentscheidungen jedes Framework-Designers besteht darin, ob ein Typ als Klasse (ein Verweistyp) oder als Struktur (ein Werttyp) designt werden soll. Ein gutes Verständnis der Unterschiede im Verhalten von Bezugstypen und Werttypen ist entscheidend für die Entscheidung.

Der erste Unterschied zwischen Verweis- und Werttypen besteht darin, dass Verweistypen auf dem Heap zugeordnet werden und für sie eine Garbage Collection durchgeführt wird. Werttypen werden dagegen entweder auf dem Stapel oder inline in enthaltenden Typen zugeordnet, und ihre Zuordnung wird aufgehoben, wenn der Stapel entladen wird oder wenn die Zuordnung ihres enthaltenen Typs aufgehoben wird. Daher sind die Zuordnung und die Aufhebung der Zuordnung von Werttypen im Allgemeinen günstiger als die Zuordnung und die Aufhebung der Zuordnung von Verweistypen.

Zweitens: Arrays von Verweistypen werden „out-of-line“ zugeordnet. Das bedeutet, dass die Arrayelemente nur Verweise auf Instanzen des Verweistyps sind, der sich auf dem Heap befindet. Werttyparrays werden inline zugeordnet, was bedeutet, dass die Arrayelemente die tatsächlichen Instanzen des Werttyps sind. Daher sind Allokationen und Freigaben von Werttypen-Arrays viel kostengünstiger als Allokationen und Freigaben von Referenztypen-Arrays. Darüber hinaus weisen Werttyparrays in den meisten Fällen eine viel bessere Positionierung von Verweisen auf.

Der nächste Unterschied bezieht sich auf die Speicherauslastung. Für Werttypen wird beim Umwandeln in einen Verweistyp oder in eine der von ihnen implementierten Schnittstellen ein Boxing-Vorgang ausgeführt. Wenn sie wieder in den Werttyp umgewandelt werden, wird ein Unboxing-Vorgang ausgeführt. Boxing-Objekte werden auf dem Heap zugeordnet und unterliegen der Garbage Collection. Daher können sich zu viele Boxing- und Unboxing-Vorgänge negativ auf den Heap, den Garbage Collector und letztendlich auf die Leistung der Anwendung auswirken. Bei der Umwandlung von Verweistypen findet dagegen kein solches Boxing statt. (Weitere Informationen finden Sie unter Boxing und Unboxing).

Als Nächstes kopieren Referenztypzuweisungen den Verweis, während Werttypzuweisungen den gesamten Wert kopieren. Daher sind Zuordnungen großer Bezugstypen günstiger als Zuordnungen großer Werttypen.

Schließlich werden Verweistypen per Referenz übergeben, während Werttypen als Wert übergeben werden. Änderungen an einer Instanz eines Verweistyps wirken sich auf alle Verweise aus, die auf die Instanz verweisen. Werttypinstanzen werden kopiert, wenn sie nach Wert übergeben werden. Wenn eine Instanz eines Werttyps geändert wird, hat sie natürlich keine Auswirkungen auf ihre Kopien. Da die Kopien nicht explizit vom Benutzer erstellt werden, aber implizit erstellt werden, wenn Argumente übergeben oder Rückgabewerte zurückgegeben werden, können Werttypen, die geändert werden können, für viele Benutzer verwirrend sein. Daher sollten Werttypen unveränderlich sein.

Als Faustregel sollten die meisten Typen in einem Framework Klassen sein. Es gibt jedoch einige Situationen, in denen die Merkmale eines Werttyps für die Verwendung von Strukturen besser geeignet sind.

✔️ ERWÄGEN SIE, eine Struktur anstelle einer Klasse zu definieren, wenn Instanzen des Typs klein und häufig kurzlebig sind oder häufig in andere Objekte eingebettet sind.

❌ VERMEIDEN Sie die Definition einer Struktur, es sei denn, der Typ weist alle folgenden Merkmale auf:

  • Er stellt logisch einen einzelnen Wert dar, ähnlich wie primitive Typen (int, doubleusw.).

  • Sie hat eine Instanzgröße unter 16 Byte.

  • Es ist unveränderlich.

  • Für ihn müssen nicht häufig Boxing-Vorgänge ausgeführt werden.

In allen anderen Fällen sollten Sie Ihre Typen als Klassen definieren.

© Teile 2005, 2009 Microsoft Corporation. Alle Rechte vorbehalten.

Nachdruck mit freundlicher Genehmigung von Pearson Education, Inc., aus dem Buch Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition von Krzysztof Cwalina und Brad Abrams, veröffentlicht am 22. Oktober 2008 von Addison-Wesley Professional als Teil der Microsoft Windows Development Series.

Siehe auch