1. Einfache Konstruktoren
Konstruktor – das ist eine spezielle Methode einer Klasse, die automatisch beim Erstellen eines Objekts aufgerufen wird. Sie initialisiert (konfiguriert) das Objekt: setzt Anfangswerte, macht Checks, kann dir sogar gute Laune machen, wenn du einen Witz reinschreibst.
Mit einem Konstruktor kannst du ein Objekt direkt in einem bestimmten Zustand erzeugen, statt alle Daten einzeln per Felder und Properties zu setzen. Das ist praktisch und sicher, weil du gleich alle wichtigen Parameter angibst – und nichts Kritisches vergisst.
Ohne Konstruktor kann der Code sperrig aussehen und fehleranfällig sein:
Person p = new Person();
p.Name = "Julia";
p.Age = 25; // Und was, wenn wir das Alter vergessen?
Mit Konstruktor:
Person p = new Person("Julia", 25); // Alles direkt übergeben und das Objekt ist startklar!
Syntax des Konstruktors
Ein Konstruktor ist eine spezielle "Methode", deren Name genau wie der Klassenname ist und die keinen Rückgabewert hat (nicht mal void). So sieht ein Standard-Konstruktor aus:
public class Person
{
// Standard-Konstruktor (ohne Parameter)
public Person()
{
// Hier kann Initialisierungscode stehen
}
}
Der Standard-Konstruktor ist so ein unsichtbarer "Helfer", der keine Parameter nimmt und einfach alle Felder und Properties deiner Klasse auf Standardwerte setzt:
- Für Zahlentypen (int, double, float usw.) ist das 0.
- Für boolesche Typen (bool) ist das false.
- Für Referenztypen (string, andere Klassen) ist das null (bedeutet "nichts", "keine Referenz auf ein Objekt").
- Für DateTime ist das 01.01.0001 00:00:00.
Wie ruft man einen Konstruktor auf?
Eigentlich: Immer wenn du beim Erstellen eines Objekts das new-Schlüsselwort benutzt, rufst du einen Konstruktor auf!
Person p = new Person();
Wenn du keinen eigenen Konstruktor definierst, erstellt der C#-Compiler für dich einen Standard-Konstruktor (ohne Parameter). Aber sobald du einen eigenen deklarierst, verschwindet der Standard-Konstruktor und der Compiler will, dass du ihn explizit hinzufügst, falls du ihn brauchst.
Beispiel
Lass uns einen Konstruktor in unsere App-Klasse einbauen. Hier eine einfache Version einer Student-Klasse:
public class Student
{
public string Name;
public int Age;
// Konstruktor mit zwei Parametern (Name und Alter)
public Student(string name, int age)
{
Name = name; // Wert zuweisen
Age = age;
}
}
Jetzt kannst du einen Studenten so erzeugen:
Student s = new Student("Ivan", 21);
Console.WriteLine($"{s.Name}: {s.Age} Jahre"); // Ivan: 21 Jahre
- Wir haben den Konstruktor mit derselben Sichtbarkeit (public) wie die Klasse deklariert.
- Im Konstruktor weisen wir die Werte den Feldern zu, mit den übergebenen Parametern.
- So schützt du dich vor Vergesslichkeit: Der Compiler verlangt Name und Alter beim Erstellen des Objekts.
2. Konstruktor-Parameter
In C# kannst du mehrere Konstruktoren mit unterschiedlichen Parameterlisten deklarieren. Das nennt man Konstruktor-Überladung (über Methodenüberladung reden wir später noch).
Zum Beispiel, wir fügen einen Konstruktor ohne Parameter hinzu:
public class Student
{
public string Name;
public int Age;
// Standard-Konstruktor
public Student()
{
Name = "Namenlos";
Age = 0;
}
// Konstruktor mit Parametern
public Student(string name, int age)
{
Name = name;
Age = age;
}
}
Jetzt gehen beide Varianten:
Student s1 = new Student(); // Name: Namenlos, Alter: 0
Student s2 = new Student("Olya", 22); // Name: Olya, Alter: 22
Konstruktor für Validierung nutzen
Der Konstruktor ist ein super Ort, um die "Qualität" der Eingabedaten zu prüfen. Zum Beispiel: Ein Student kann kein negatives Alter haben!
public Student(string name, int age)
{
if (age < 0)
throw new ArgumentException("Alter darf nicht negativ sein!");
Name = name;
Age = age;
}
Jetzt, wenn jemand versucht, einen Studenten Student("LittleOne", -2) zu erstellen, wirft die App eine Exception (ArgumentException). So ein Ansatz wird oft für "bombensichere" Daten verwendet.
3. Initialisierung komplexer Objekte
Oft besteht ein Objekt in echten Anwendungen nicht nur aus primitiven Typen, sondern enthält andere Objekte:
public class Group
{
public string GroupName;
public Student[] Students;
public Group(string groupName, Student[] students)
{
GroupName = groupName;
Students = students;
}
}
Jetzt kannst du easy eine Gruppe mit einer Studentensammlung erstellen:
var students = new Student[]
{
new Student("Ivan", 20),
new Student("Maria", 19)
};
Group g = new Group("Gruppe-101", students);
Felder mit Standardwerten initialisieren
Manchmal willst du für manche Felder Standardwerte setzen, falls nicht alle Parameter im Konstruktor übergeben werden. Zum Beispiel, wenn E-Mail nicht Pflicht ist:
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "unbekannt@noemail.com"; // Standardwert
}
4. Initialisierung mit Object Initializer
Mit Konstruktoren kannst du auch einen anderen praktischen Syntax kombinieren – Object Initializer. Du rufst den Konstruktor auf und kannst dann in geschweiften Klammern Properties setzen:
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
// Konstruktor wird trotzdem empfohlen
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "";
}
}
Student s = new Student("Anton", 18) { Email = "anton@domain.com" }; // Konstruktor + Properties
Dieser Syntax ist super, wenn du einen Konstruktor hast, aber manche Parameter Standardwerte haben oder nicht immer beim Erstellen bekannt sind.
5. Typische Fehler und Besonderheiten
Beim Arbeiten mit Konstruktoren machen Einsteiger oft ein paar typische Fehler. Lass uns die mal ganz locker anschauen:
Fehler Nr. 1: Namensverwechslung
Manchmal werden Parameter- und Feldnamen verwechselt, vor allem wenn sie sich nur durch Groß-/Kleinschreibung unterscheiden.
public Student(string Name, int Age) // Mit großem Buchstaben!
{
Name = Name; // Ups! Beide Name beziehen sich auf den Parameter. Das Feld bleibt uninitialisiert.
}
Wie richtig: Benutze this für den Bezug auf das Feld des Objekts:
public Student(string name, int age)
{
this.Name = name;
this.Age = age;
}
Oder einfach unterschiedliche Namen wählen (z.B. nameParam, ageParam), aber die this.-Variante gilt als guter Stil, besonders in größeren Projekten.
Fehler Nr. 2: Kein Standard-Konstruktor
Wenn du mindestens einen Konstruktor deklarierst und dann versuchst, ein Objekt ohne Parameter zu erstellen – bekommst du einen Compiler-Fehler:
public class Student
{
public Student(string name) { /*...*/ }
}
// irgendwo im Code
Student s = new Student(); // Fehler! Kein Konstruktor ohne Parameter.
Lösung: Füge explizit einen Konstruktor ohne Parameter hinzu:
public Student() { /*...*/ }
Fehler Nr. 3: Endlose Rekursion – wenn der Konstruktor sich selbst aufruft
public Student()
{
// Fehler! Ruft sich selbst auf – endlose Rekursion.
new Student();
}
GO TO FULL VERSION