Auswählen zwischen Klasse und Struktur

Hinweis

Diese Inhalte wurden mit Genehmigung von Pearson Education, Inc. aus Framework Design Guidelines nachgedruckt: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. 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, die alle Frameworkdesigner*innen zu treffen haben, ist, ob sie einen Typ als Klasse (Verweistyp) oder als Struktur (Werttyp) entwerfen. Hierzu ist es wichtig, gut mit den Verhaltensunterschieden zwischen Verweis- und Werttypen vertraut zu sein.

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 die Zuordnung und die Aufhebung der Zuordnung von Werttyparrays deutlich günstiger als die Zuordnung und die Aufhebung der Zuordnung von Verweistyparrays. Darüber hinaus weisen Werttyparrays in den meisten Fällen eine viel bessere Positionierung von Verweisen auf.

Der nächste Unterschied hängt mit der Speicherauslastung zusammen. 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 (C#-Programmierhandbuch).

Nächster Punkt: Verweistypzuweisungen kopieren den Verweis, während Werttypzuweisungen den gesamten Wert kopieren. Daher sind Zuweisungen großer Verweistypen günstiger als Zuweisungen großer Werttypen.

Und schließlich werden Verweistypen durch Verweis übergeben, während Werttypen nach Wert übergeben werden. Änderungen an einer Instanz eines Verweistyps wirken sich auf alle Verweise aus, die auf die Instanz zeigen. Werttypinstanzen werden kopiert, wenn sie nach Wert übergeben werden. Wenn eine Instanz eines Werttyps geändert wird, wirkt sich dies natürlich nicht auf seine Kopien aus. Da die Kopien nicht explizit von Benutzer*innen erstellt werden, sondern implizit, wenn Argumente übergeben oder Rückgabewerte zurückgegeben werden, können Werttypen, die geändert werden können, für Benutzer*innen verwirrend sein. Daher sollten Werttypen unveränderlich sein.

Faustregel: Bei der Mehrheit der Typen in einem Framework sollte es sich um Klassen handeln. Es gibt allerdings Situationen, in denen Strukturen aufgrund der Merkmale eines Werttyps besser geeignet sind.

✔️ Erwägen Sie, eine Struktur anstelle einer Klasse zu definieren, wenn Instanzen des Typs klein und in der Regel kurzlebig sind oder häufig in andere Objekte eingebettet werden.

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

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

  • Seine Instanzgröße ist kleiner als 16 Bytes.

  • Er 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 Genehmigung von Pearson Education, Inc aus 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 durch Addison-Wesley Professional als Teil der Microsoft Windows Development Series.

Weitere Informationen