struct vs class in C#

Der wichtigste Unterschied: Value Type vs Reference Type

📦 struct (Value Type)

  • ✓ Wird auf dem Stack gespeichert
  • ✓ Beim Zuweisen wird kopiert
  • ✓ Schneller für kleine Daten
  • ✓ Keine Vererbung möglich
  • ✓ Kann nicht null sein (außer Nullable)
  • ✓ Gut für: Koordinaten, Farben, kleine Daten

🔗 class (Reference Type)

  • ✓ Wird auf dem Heap gespeichert
  • ✓ Beim Zuweisen wird Referenz kopiert
  • ✓ Besser für große Objekte
  • ✓ Vererbung möglich
  • ✓ Kann null sein
  • ✓ Gut für: Komplexe Objekte, OOP

🔬 Beweis 1: Kopierverhalten

struct Point (Value Type)

public struct Point { public int X; public int Y; public Point(int x, int y) { X = x; Y = y; } } // Test: Point p1 = new Point(10, 20); Point p2 = p1; // KOPIE! p2.X = 999; // Ändert nur p2 Console.WriteLine($"p1.X = {p1.X}"); Console.WriteLine($"p2.X = {p2.X}");

class Person (Reference Type)

public class Person { public int Age; public string Name; public Person(int age, string name) { Age = age; Name = name; } } // Test: Person person1 = new Person(25, "Max"); Person person2 = person1; // REFERENZ! person2.Age = 999; // Ändert beide! Console.WriteLine($"person1.Age = {person1.Age}"); Console.WriteLine($"person2.Age = {person2.Age}");

💡 Ergebnis:

struct: p1.X bleibt 10, weil p2 eine KOPIE ist
class: person1.Age wird auch 999, weil person2 auf dasselbe Objekt zeigt

🔬 Beweis 2: Methoden-Parameter

struct als Parameter

public static void ModifyPoint(Point p) { p.X = 9999; Console.WriteLine($"In Methode: {p.X}"); } // Test: Point original = new Point(5, 5); Console.WriteLine($"Vorher: {original.X}"); ModifyPoint(original); // Übergibt KOPIE Console.WriteLine($"Nachher: {original.X}");

class als Parameter

public static void ModifyPerson(Person p) { p.Age = 9999; Console.WriteLine($"In Methode: {p.Age}"); } // Test: Person original = new Person(30, "Anna"); Console.WriteLine($"Vorher: {original.Age}"); ModifyPerson(original); // Übergibt REFERENZ Console.WriteLine($"Nachher: {original.Age}");

💡 Ergebnis:

struct: original.X bleibt 5 (Methode bekommt Kopie)
class: original.Age wird 9999 (Methode bekommt Referenz)

🔬 Beweis 3: ref Keyword bei struct

public static void ModifyPointByRef(ref Point p) { p.X = 7777; Console.WriteLine($"In Methode: {p.X}"); } // Test: Point original = new Point(100, 200); Console.WriteLine($"Vorher: {original.X}"); ModifyPointByRef(ref original); // Übergibt REFERENZ zur Kopie Console.WriteLine($"Nachher: {original.X}");

💡 Ergebnis:

Mit ref kann auch ein struct per Referenz übergeben werden. Dann wird das Original verändert!

📊 Vergleichstabelle

Eigenschaft struct class
Typ Value Type Reference Type
Speicher Stack Heap
Zuweisung Wert wird kopiert Referenz wird kopiert
null möglich? Nein (außer Nullable<T>) Ja
Vererbung Nicht möglich Möglich
Standardkonstruktor Immer vorhanden Nur wenn nicht überschrieben
Performance Schneller für kleine Daten Besser für große Objekte
Typische Verwendung Point, Color, DateTime, Koordinaten Person, Auto, komplexe Objekte

✅ Verwende struct wenn:

  • • Objekte klein sind (< 16 Bytes empfohlen)
  • • Objekte nicht vererbt werden müssen
  • • Kopierverhalten gewünscht ist
  • • Immutabilität gewünscht ist
  • • Beispiele: Point, Rectangle, Color, DateTime

✅ Verwende class wenn:

  • • Objekte komplex/groß sind
  • • Vererbung benötigt wird
  • • Referenzverhalten gewünscht ist
  • • null-Werte möglich sein sollen
  • • Beispiele: Person, Auto, Datenbank-Objekte