Vom C# Sprachspezifikation:
1.7 Strukturen
Ähnlich wie Klassen sind Strukturen Datenstrukturen, die Datenmember und Funktionen enthalten können, aber im Gegensatz zu Klassen sind Strukturen Werttypen und erfordern keine Speicherplatzzuweisung im Heap. Eine Variable eines Strukturtyps speichert die Daten der Struktur direkt, während eine Variable eines Klasstyps eine Referenz auf ein dynamisch allokiertes Objekt speichert. Strukturtypen unterstützen keine benutzerdefinierte Vererbung und alle Strukturtypen erben implizit vom Typ "object".
Strukturen sind besonders nützlich für kleine Datenstrukturen mit Wertsemantik. Komplexe Zahlen, Punkte in einem Koordinatensystem oder Schlüssel-Wert-Paare in einem Wörterbuch sind alles gute Beispiele für Strukturen. Die Verwendung von Strukturen anstelle von Klassen für kleine Datenstrukturen kann einen großen Unterschied in der Anzahl der Speicherplatzzuweisungen ausmachen, die eine Anwendung durchführt. Zum Beispiel erstellt und initialisiert das folgende Programm ein Array von 100 Punkten. Mit Point implementiert als Klasse werden 101 separate Objekte instanziiert – eins für das Array und jeweils eins für die 100 Elemente.
class Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Test
{
static void Main() {
Point[] points = new Point[100];
for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
}
}
Ein alternativer Ansatz ist es, Point zu einer Struktur zu machen.
struct Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Jetzt wird nur ein Objekt instanziiert – das für das Array – und die Point-Instanzen werden inline im Array gespeichert.
Strukturkonstruktoren werden mit dem new-Operator aufgerufen, was jedoch nicht bedeutet, dass Speicherplatz zugeordnet wird. Anstatt ein Objekt dynamisch zuzuweisen und eine Referenz darauf zurückzugeben, gibt ein Strukturkonstruktor einfach den Strukturwert selbst zurück (normalerweise an einem temporären Ort auf dem Stapel), und dieser Wert wird bei Bedarf kopiert.
Bei Klassen ist es möglich, dass zwei Variablen auf dasselbe Objekt verweisen und somit Operationen auf einer Variablen das von der anderen Variablen referenzierte Objekt beeinflussen können. Bei Strukturen haben die Variablen jeweils ihre eigene Kopie der Daten, und es ist nicht möglich, dass Operationen auf eine die andere beeinflussen. Zum Beispiel hängt die Ausgabe des folgenden Codefragments davon ab, ob Point eine Klasse oder eine Struktur ist.
Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);
Wenn Point eine Klasse ist, ist die Ausgabe 20, weil a und b auf dasselbe Objekt verweisen. Wenn Point eine Struktur ist, ist die Ausgabe 10, weil die Zuweisung von a an b eine Kopie des Werts erstellt und diese Kopie durch die nachfolgende Zuweisung an a.x nicht beeinflusst wird.
Das vorherige Beispiel verdeutlicht zwei der Einschränkungen von Strukturen. Erstens ist das Kopieren einer kompletten Struktur in der Regel weniger effizient als das Kopieren einer Objektreferenz, sodass Zuweisungen und Wertparameterübergaben bei Strukturen teurer sein können als bei Verweistypen. Zweitens ist es abgesehen von ref- und out-Parametern nicht möglich, Verweise auf Strukturen zu erstellen, was ihren Einsatz in einer Reihe von Situationen ausschließt.
0 Stimmen
Ich kann nur dem ersten Punkt zustimmen, Strukturen werden zum Beispiel sehr häufig in der Spieleprogrammierung verwendet.
305 Stimmen
System.Drawing.Rectangle
verletzt alle drei dieser Regeln.3 Stimmen
Ja, nun gut, zumindest Teile davon. Ich weiß, dass es für Teile von Spielen verwendet wird, wie NWN2 World Creator. C ist in der Regel immer noch das Kernelement (Engine). XNA Game Studio, Google es :)
7 Stimmen
Es gibt ziemlich viele kommerzielle Spiele, die in C# geschrieben sind, der Punkt ist, dass sie für optimierten Code verwendet werden.
2 Stimmen
Ich verwende sie manchmal für Zeichenfolgenwerte "enums".
4 Stimmen
Eine weitere Situation, in der Sie Strukturen verwenden sollten, ist, wenn Ihre Objekte keine Identität benötigen.
1 Stimmen
Ich bin immer nach dem Denken in der zweiten Bearbeitung der Frage gegangen: Wenn ich eine Handvoll verwandter Werttypen habe, erstelle ich eine Struktur. Ich könnte mehrere dieser kleinen Dateneinheiten haben und möchte wirklich nicht viele zusätzliche Klassendateien erstellen für das, was nur ein paar Dutzend Codezeilen wären.
1 Stimmen
Sie verwenden Strukturen, wenn Sie Ihre Klasse nicht vererben möchten. Das ist großartig, wenn Sie Objekte erstellen möchten, die nur Daten halten.
36 Stimmen
Strukturen bieten eine bessere Leistung, wenn Sie kleine Sammlungen von Werttypen haben, die Sie zusammen gruppieren möchten. Das passiert die ganze Zeit beim Spielprogrammieren, zum Beispiel wird ein Eckpunkt in einem 3D-Modell eine Position, eine Texturkoordinate und eine Normale haben, außerdem wird er in der Regel unveränderlich sein. Ein einzelnes Modell kann ein paar tausend Eckpunkte haben oder auch nur ein Dutzend, aber Strukturen bieten insgesamt weniger Overhead in diesem Nutzungsszenario. Das habe ich durch mein eigenes Engine-Design verifiziert.
0 Stimmen
Ich würde Strukturen für die Verbindung von nicht verwaltetem Code und leichtgewichtige statische Datensätze verwenden. Der Kompromiss zwischen Leistungssteigerung durch Speicherverwaltung und mangelnder Erweiterbarkeit im Design.
3 Stimmen
Das ist der völlig falsche Grund, um sich für Strukturen anstelle von Klassen zu entscheiden
6 Stimmen
@ErikForbes: Ich denke, dies wird allgemein als der größte BCL "oops" angesehen
0 Stimmen
@ChrisW: Der größte Defekt in
Rechteck
ist, dass seine Elemente Eigenschaften anstatt Felder sind. Die Verwendung von struct Eigenschaften, wenn Felder ausgereicht hätten, ist wahrscheinlich zu 95% für die Vorstellung verantwortlich, dass "veränderbare structs böse sind" (es gibt legitime Verwendungen für Eigenschaften-Setter in schreibgeschützten Strukturinstanzen; deshalb hat C# erst kürzlich ihre Verwendung verboten (legitime Anwendungsfälle ausschließend); Strukturen, die Elemente in Lese-Schreib-Eigenschaften einhüllten, verwandelten effektiv Code, der Compilerfehler hätte erzeugen sollen, in Code, der kompilierte, aber nicht funktionierte.0 Stimmen
Möglicher Duplikat von Wann sollte ich eine Struktur anstelle einer Klasse verwenden?
0 Stimmen
Ein interessanter Punkt könnte sein, wann sollte ich Strukturen mit Methoden verwenden, weil jeder Methode 1 Wort (16 Bytes) mehr in Bezug auf die Struktursumme .. also wird diese Struktur offensichtlich schwer genug sein, um Regel #2 zu brechen und die Leistungsfähigkeit zu beeinträchtigen
2 Stimmen
@ChrisW Stellt
System.Drawing.Rectangle
nicht einen einzigen Wert dar? Könnten Sie das bitte erklären?0 Stimmen
@MarsonMao Es stellt eine linke, eine rechte, eine obere, eine untere, eine Höhe und eine Breite dar (d. h. 6 Werte, zugegebenermaßen miteinander verwandte Werte).
8 Stimmen
@ChrisW Ich sehe, aber repräsentieren diese Werte nicht ein Rechteck, das heißt, einen "einzigen" Wert? Wie Vector3D oder Color, sie enthalten auch mehrere Werte, aber ich denke, sie repräsentieren einzelne Werte?
2 Stimmen
@MarsonMao Eines der bestimmenden Merkmale einer Struktur ist, dass es sich um eine Gruppe von verwandten Werten handelt, die als einzelner Wert behandelt werden sollen. Ein Rechteck erfüllt diese Eigenschaft sicherlich. Ich glaube, dass Chris versucht, Haare in der Wortwahl dieses Punktes zu spalten.
2 Stimmen
Beide Links sind defekt.
1 Stimmen
@weberc2 Chris sagt, diese Liste sollte nicht verwendet werden, um zu definieren, ob eine Struktur verwendet werden soll. Gegenbeispiel ist
Rechteck
: etwas, das auf jeden Fall eine Struktur sein sollte, aber trotzdem all dies verletzt. Daher sind sie keine guten Bedingungen.0 Stimmen
Das war eine gute Frage. Ich habe viel über die Unterschiede gelesen und hier habe ich schließlich die Antwort gefunden.