1. Automatische Properties
In C# sind Properties (property) so was wie ein Mix aus Feld und Methode. Im Grunde ist das syntactic sugar, der die Arbeit mit Kapselung super bequem macht. Du greifst auf eine Property zu, als wäre es ein Feld, aber intern kann da alles Mögliche passieren: Daten prüfen, andere Felder ändern, Methoden aufrufen oder sogar deiner Oma eine E-Mail schicken (das Letzte ist aber nicht zu empfehlen). In der letzten Vorlesung haben wir Properties noch von Hand geschrieben. Das kann aber schnell nerven, wenn du 100500 simple Objekte hast, wo du nur einen "Getter" und "Setter" brauchst – ohne extra Logik.
Hier kommen die automatischen Properties. Die nehmen dir den Boilerplate-Kram ab und lassen C# das Speichern des Werts für dich erledigen.
Wie es früher war: Properties von Hand
Wenn wir ein Feld verstecken, aber trotzdem Zugriff über eine Property geben wollen, schreiben wir meistens sowas:
public class Dog
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
Solcher Code ist das typische "Boilerplate"-Genöle. Und meistens muss man in get/set gar nichts extra machen! Einfach Zugriff geben – fertig.
Wie es jetzt geht
In C# ist das jetzt viel entspannter: Du musst keine Felder mehr von Hand schreiben – das übernimmt der Compiler. Es reicht:
public class Dog
{
public string Name { get; set; }
}
Und das war's. Du kannst Name ganz normal lesen und ändern, und unter der Haube legt der Compiler ein privates Feld an, auf das du von außen nicht direkt zugreifen kannst.
Was passiert da eigentlich im Hintergrund? Wenn du public string Name { get; set; } schreibst, erzeugt der Compiler automatisch ein verstecktes Feld wie Name__BackingField. Bei jedem Zugriff auf Name wird der passende Getter oder Setter eingefügt. Das Feld selbst siehst du im Code nicht, aber es existiert – und mit Reflection kannst du es sogar finden (aber das ist eine andere Story).
Was ist daran cool? Erstens: Es ist viel kürzer und du musst dich nicht ständig wiederholen. Zweitens: Der Code ist cleaner – weniger visuelles Rauschen, leichter zu lesen und zu pflegen. Und schließlich: Es ist sicherer – niemand kann direkt an den Feldern rumfummeln, der Zugriff läuft immer über Properties.
2. Syntax für automatische Properties
Der Syntax ist super simpel:
public class Dog
{
public string Name { get; set; }
public int Age { get; set; }
}
Jetzt sieht unser Dog viel schlanker aus! Wir können Objekte anlegen und Werte wie gewohnt setzen:
Dog myDog = new Dog();
myDog.Name = "Barbos";
myDog.Age = 4;
Schematisch
| Variante | Syntax | Zugriff auf Wert |
|---|---|---|
| Feld | |
Direkter Zugriff |
| Property von Hand | |
Zugriff über get/set |
| Auto-Property | |
get/set + verstecktes Feld |
3. Zugriff anpassen: Nur lesen, nur schreiben
Nur lesen: get-only
Wenn du eine Property nur lesen willst (z.B. eine Registrierungsnummer vom Haustier), kannst du sie als read-only machen – einfach nur get angeben, set weglassen oder privat machen. Den Wert kannst du dann nur im Konstruktor oder direkt beim Deklarieren setzen:
public class Dog
{
public string RegistrationCode { get; }
public Dog()
{
RegistrationCode = "DOG-001"; // Wert im Konstruktor setzen
}
}
Jetzt kannst du RegistrationCode von außen nur lesen, aber nicht ändern. Perfekt, um wichtige Daten vor versehentlichen Änderungen zu schützen.
Noch ein Weg: privater set
public string Name { get; private set; }
Dann kann die Property nur innerhalb der Klasse geändert werden (z.B. über eine Methode oder im Konstruktor).
Nur schreiben: schlechte Idee
Theoretisch kannst du auch eine set-only Property machen (nur schreiben), aber das ist extrem selten und nicht zu empfehlen – stell dir ein Objekt vor, das wie ein "Schwarzes Loch" ist: Du kannst was reinschmeißen, aber nie wieder rausholen.
4. init-only Setter
Kurz zur Vorgeschichte
Früher, wenn du ein unveränderliches Objekt (immutable) wolltest, musstest du nur get-Properties schreiben und die Werte im Konstruktor setzen. Okay, das geht – aber nicht immer praktisch. Seit kurzem gibt's in C# aber einen neuen Syntax: init-only Properties.
Was bringt der init-Setter?
- Du kannst den Wert der Property nur beim Erstellen des Objekts setzen (also im Konstruktor oder im Objekt-Initializer).
- Nach dem Erstellen ist die Property nur noch lesbar.
- Perfekt für "fast immutable" Klassen, DTOs, Configs, Models.
public class Dog
{
public string Name { get; init; }
public int Age { get; init; }
}
Jetzt kannst du sowas machen:
Dog dog = new Dog { Name = "Bobik", Age = 2 };
dog.Name = "Rex"; // Fehler! Nach dem Erstellen nur noch lesen
Im Konstruktor kannst du die Werte auch setzen:
public Dog(string name, int age)
{
Name = name;
Age = age;
}
Schaubild: Wann kann man zuweisen?
| Wo zuweisen? | { get; set; } | { get; private set; } | { get; init; } |
|---|---|---|---|
| Außerhalb der Klasse, nach dem Erstellen | ✅ | ❌ | ❌ |
| Im Konstruktor | ✅ | ✅ | ✅ |
| Im Initializer | ✅ | ❌ | ✅ |
| Innerhalb der Klasse | ✅ | ✅ | ❌ (außer im Konstruktor) |
5. Anwendung in der Praxis
Lass uns unsere Dog-Klasse mit automatischen und init-only Properties neu schreiben:
public class Dog
{
// Property, nur beim Initialisieren setzen
public string Name { get; init; }
public int Age { get; init; }
// Automatische Property für aktuellen Zustand
public bool IsHungry { get; set; }
// Methode, Aktion des Hundes
public void Bark()
{
Console.WriteLine($"{Name} sagt: Wuff!");
}
}
Jetzt können wir Dog so anlegen:
Dog dog = new Dog { Name = "Sharik", Age = 3, IsHungry = true };
dog.Bark(); // gibt aus: Sharik sagt: Wuff!
dog.IsHungry = false; // Diese Property kannst du nach dem Erstellen ändern
dog.Name = "Barbos"; // Fehler! Property nur beim Initialisieren
6. Automatische Properties mit Standardwerten
In C# ist alles auf Bequemlichkeit ausgelegt. Du kannst sogar gleich einen Standardwert für die Property setzen:
public class Dog
{
public string Name { get; set; } = "Namenlos";
public int Age { get; set; } = 0;
}
Oder mit init:
public class Dog
{
public string Name { get; init; } = "Welpe";
public int Age { get; init; } = 0;
}
Wenn du jetzt beim Erstellen keinen Name angibst, ist er "Welpe".
7. Automatische Properties mit verschiedenen Zugriffen
Du kannst Properties so machen, dass sie mit unterschiedlichen Zugriffsmodifizierern gelesen und geschrieben werden:
public class Dog
{
public string Name { get; private set; }
public int Age { get; private set; }
public Dog(string name, int age)
{
Name = name;
Age = age;
}
}
Hier kannst du Name und Age nur innerhalb der Klasse Dog ändern, z.B. in Methoden oder im Konstruktor.
Vergleich: Properties von Hand vs. automatisch
| Variante | Schreibaufwand | Kontrolle in set/get | Änderbarkeit nach Erstellen | Einsatz in Modellen |
|---|---|---|---|---|
| Property von Hand | Lang | Voll | Beliebig | Wenn Logik gebraucht wird |
| Automatische Property | Kurz | Keine | Beliebig oder privat | Fast überall |
| init-only automatisch | Kurz | Keine | Nur beim Erstellen | DTO, Configs |
8. Typische Fehler bei Properties
Fehler Nr. 1: Versuch, einer get-only Property außerhalb des Konstruktors einen Wert zuzuweisen.
Wenn eine Property nur get hat, lässt der Compiler keine Wertzuweisung außerhalb des Konstruktors oder der Deklaration zu. Vergisst du das, gibt's einen Compile-Error.
Fehler Nr. 2: Verwechslung von Feld und Property.
Wenn du ein Feld durch eine automatische Property ersetzt, musst du sicherstellen, dass im restlichen Code kein direkter Zugriff aufs Feld mehr passiert. Feld und Property sind verschiedene Dinge, und wenn du alte Zugriffe stehen lässt, gibt's entweder einen Fehler oder das Programm macht komische Sachen.
Fehler Nr. 3: privater set ohne zu checken, was das bedeutet.
Wenn eine Property einen privaten set hat, aber im restlichen Code trotzdem versucht wird, ihr einen Wert zuzuweisen – gibt's einen Fehler. Das passiert oft aus Versehen, vor allem beim Copy-Paste von fremdem Code. Check immer, ob set da verfügbar ist, wo du ihn brauchst.
GO TO FULL VERSION