Struct oder Class in C#: Die ewige Debatte zwischen Anfängern und Profis
\n\nHaben Sie sich jemals gefragt, warum es in C# zwei sehr ähnliche Möglichkeiten gibt, einen eigenen Datentyp zu erstellen – class und struct? Und warum die Frage „When should I use a struct rather than a class in C#?“ auf Stack Overflow tausende Aufrufe und hunderte Antworten sammelt? Die Sache ist die, dass sich hinter der scheinbaren Einfachheit eine tiefgreifende Nuance verbirgt, die Ihr Programm sowohl beschleunigen als auch in eine Brutstätte von Fehlern verwandeln kann.
In diesem Artikel analysieren wir, worin sich struct von class unterscheidet, wann man struct verwenden sollte und wann man seine Existenz besser vergisst. Ohne Fachchinesisch, mit lebendigen Beispielen und praktischen Tipps. Los geht's!
\n\nDer Hauptunterschied: Stack oder Heap?
\n\nDer wichtigste Punkt, den man verstehen muss, sind Werttypen (value types) und Referenztypen (reference types).
\n\n- \n
- Class – ein Referenztyp. Das Objekt wird im verwalteten Heap gespeichert, und die Variable enthält nur einen Verweis (Adresse) auf dieses Objekt. \n
- Struct – ein Werttyp (value type). Die Variable speichert die Daten selbst direkt auf dem Stack oder innerhalb eines anderen Objekts. \n
Klingt abstrakt? Betrachten wir ein Beispiel. Stellen Sie sich vor, die Daten sind ein Buch. Class ist der Buchtitel und die Regalnummer, wo es in der Bibliothek steht. Struct ist das Buch selbst, das Sie in der Tasche tragen. Wenn Sie eine class an eine Methode übergeben, übergeben Sie die Regalnummer. Wenn Sie eine struct übergeben – geben Sie eine Kopie des Buches ab.
\n\nCodebeispiel: class vs struct
\n\npublic class PointClass\n{\n public int X { get; set; }\n public int Y { get; set; }\n\n public PointClass(int x, int y)\n {\n X = x;\n Y = y;\n }\n}\n\npublic struct PointStruct\n{\n public int X { get; set; }\n public int Y { get; set; }\n\n public PointStruct(int x, int y)\n {\n X = x;\n Y = y;\n }\n}\n\n// Verwendung\nvar pointClass = new PointClass(10, 20);\nvar pointStruct = new PointStruct(10, 20);\n\n// Übergabe an eine Methode\nvoid ModifyPointClass(PointClass p) { p.X = 100; }\nvoid ModifyPointStruct(PointStruct p) { p.X = 100; }\n\nModifyPointClass(pointClass); // pointClass.X wird 100\nModifyPointStruct(pointStruct); // pointStruct.X bleibt 10 – eine Kopie!\n\n\nSehen Sie? Struct wird bei der Übergabe kopiert. Das ist der entscheidende Unterschied, der bestimmt, wann man sie verwenden sollte.
\n\nWann struct Ihr Freund ist: 3 eiserne Fälle
\n\nMicrosoft empfiehlt, struct zu verwenden, wenn Ihr Datentyp ALLE folgenden Bedingungen erfüllt:
1. Daten sind klein und einfach
\nStruct eignet sich ideal für kleine Datensätze (empfohlen nicht mehr als 16-24 Bytes). Zum Beispiel ein Punkt, eine Farbe, ein Vektor, eine komplexe Zahl, Koordinaten.
\n\npublic struct RgbColor\n{\n public byte R { get; }\n public byte G { get; }\n public byte B { get; }\n\n public RgbColor(byte r, byte g, byte b)\n {\n R = r;\n G = g;\n B = b;\n }\n}\n\n\nWarum? Weil kleine structs schnell kopiert werden und die Speicherung auf dem Stack die Belastung des Garbage Collectors (GC) reduziert.
\n\n2. Objekte leben kurz und ändern sich nicht
\nWenn Ihre Daten unveränderliche (immutable) Werte sind, ist struct eine ausgezeichnete Wahl. Zum Beispiel Koordinaten auf einer Karte: Sie ändern keinen Punkt, Sie erstellen einen neuen.
\n\npublic struct GeoLocation\n{\n public double Latitude { get; }\n public double Longitude { get; }\n\n public GeoLocation(double lat, double lon)\n {\n Latitude = lat;\n Longitude = lon;\n }\n\n public GeoLocation MoveNorth(double meters)\n {\n // Gibt eine neue Instanz zurück, ändert die alte nicht\n return new GeoLocation(Latitude + meters / 111111.0, Longitude);\n }\n}\n\n\n