CodeGym /Kurse /C# SELF /Extension Members: Eigenschaften

Extension Members: Eigenschaften

C# SELF
Level 18, Lektion 3
Verfügbar

1. Einführung

Früher konntest du Klassen nur Extension-Methoden hinzufügen. Aber eine Property (property) als Erweiterung ging nicht! Wenn du also wolltest, dass z.B. jeder DateTime eine Property IsWeekend bekommt, musstest du das als Methode machen – was nicht immer praktisch ist, vor allem wenn du lieber date.IsWeekend statt date.IsWeekend() schreiben willst.

Mit C# 14 ist der Traum wahr geworden: Jetzt kannst du Extension Properties fast wie Methoden schreiben. Damit kannst du einem bestehenden Typ eine neue Property hinzufügen, ohne den Originalcode zu ändern – und du benutzt sie wie eine ganz normale Property!

Wo ist das wirklich nützlich?

  • Für Standardtypen aus .NET und externe Bibliotheken, deren Code du nicht ändern kannst.
  • Für praktische „virtuelle“ Properties in ViewModels, UI, berechneten Views.
  • Überall, wo du einen schönen Syntax wie .SomeCalculatedProperty ohne Klammern willst.

2. Neuer Syntax in C# 14

In C# 14 wurde das Schlüsselwort this für Erweiterungen abgeschafft. Stattdessen gibt es jetzt den speziellen Operator extension(Type this). Damit kannst du neue virtuelle Members zu einer Klasse hinzufügen.

Alter Syntax

public static class StringExtensions
{
    public static bool IsNullOrWhiteSpace(this string str)
        => string.IsNullOrWhiteSpace(str);
}

Neuer Syntax


public static class Enumerable
{
    extension(TSource source)
    {
        // Virtuelle Members für das Objekt
    }

    extension(TSource)
    {
        // Virtuelle statische Members
    }
}
Neuer Syntax für extension members (C# 14+)

Wichtig! Dieser neue extension-Syntax funktioniert nur in C# 14+ und .NET 10+. Wenn du noch .NET 9 benutzt, klappt das nicht. Aber falls du es ausprobieren willst und .NET 10 noch nicht draußen ist, installiere dir .NET 10 preview 5+
Hinweis! Unser C#-Kurs nutzt die neuesten Features von C# 14+, sogar die, die noch nicht offiziell draußen sind. Im Herbst 2025 kommt .NET 10 raus, und wenn du den Kurs abgeschlossen hast, bist du richtig up-to-date mit C#! 😎

3. Syntax für Extension Properties

Wie sieht das aus?

Angenommen, du willst dem Typ DateTime eine Property hinzufügen, die zurückgibt, ob das Datum ein Wochenende ist:

public static class DateTimeExtensions
{
    public static bool IsWeekend(this DateTime date) => 
        date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
}

Aber das ist der alte Weg mit Extension Method, und du rufst es so auf: myDate.IsWeekend()

Neuer Stil – Extension Property


public static class DateTimeExtensions
{
    extension(DateTime source)
    {
        public bool IsWeekend // Extension Property!
        {
            get => source.DayOfWeek == DayOfWeek.Saturday || source.DayOfWeek == DayOfWeek.Sunday;
        }        
    }
}

Jetzt kannst du so schreiben:

DateTime today = DateTime.Now;
if (today.IsWeekend)
{
    Console.WriteLine("Du kannst länger schlafen!");
}

4. Welche Extension Properties gibt es?

Du kannst nicht nur read-only Properties hinzufügen, sondern auch read-write:


public static class DateTimeExtensions
{
    extension(DateTime source)
    {
        public int YearFrom1900 // Extension Property!
        {
            get => source.Year - 1900;
            set => source.Year = value + 1900; 
        }        
    }
}
Read-write Extension Property
Wichtig: Bei read-write Extension Properties musst du wissen, dass sie das Objekt selbst verändern, aber keinen eigenen Wert irgendwo speichern können (wie ein automatisches Feld). Wenn du eine Property hinzufügen willst, die physisch nicht im Objekt existiert, brauchst du einen separaten Storage (z.B. Dictionary) – das geht aber über die Basics hinaus.

5. Statische Properties

Mit dem neuen Syntax kannst du virtuelle Properties nicht nur dem Objekt, sondern auch der Klasse hinzufügen! Ja, richtig gelesen: Jetzt kannst du virtuelle statische Properties zu einer Klasse hinzufügen. Der Syntax ist fast gleich:


public static class DateTimeExtensions
{
    // Neuer Syntax: extension block für DateTime (C# 14)
    extension(DateTime)
    {
        // Statische Property für die aktuelle Zeitzone des Users
        private static TimeZoneInfo _currentTimeZone = TimeZoneInfo.Local;

        // Extension Property für Zugriff auf die aktuelle Zeitzone
        public static TimeZoneInfo CurrentTimeZone
        {
            get => _currentTimeZone;
            set => _currentTimeZone = value ?? TimeZoneInfo.Local;
        }

        // Gibt die Zeit in der User-Zeitzone zurück
        public DateTime InCurrentTimeZone
        {
            get => TimeZoneInfo.ConvertTime(this, CurrentTimeZone);
        }
    }
}

6. Beispiele: Wir erweitern die Klasse Dog!

Lass uns weiter an unserer Hunde-App basteln, die wir schon seit mehreren Vorlesungen pflegen.

Angenommen, wir haben jetzt nicht nur Hunde, sondern auch eine Liste ihrer Impfungen (List<DateTime>), aber die Klasse Dog kommt aus einer externen Bibliothek und wir können den Code nicht ändern. Wir wollen eine Property hinzufügen: Sind alle nötigen Impfungen dieses Jahr gemacht?

Alter Weg (Extension Method):

public static class DogExtensions
{
    public static bool AllVaccinatedThisYear(this Dog dog)
    {
        return dog.Vaccinations.Any(v => v.Year == DateTime.Now.Year);
    }
}
// Verwendung:
if (myDog.AllVaccinatedThisYear())
    Console.WriteLine("Der Hund ist gesund!");

Neuer Weg (Extension Property):


public static class DogExtensions
{
    extension(Dog)
    {
        public bool AllVaccinatedThisYear
        {
            get => Vaccinations.Any(v => v.Year == DateTime.Now.Year);
        }
    }
}

// Verwendung:
if (myDog.AllVaccinatedThisYear)
    Console.WriteLine("Der Hund ist gesund!");

Komplettes Beispiel

// Klasse Dog – z.B. aus einer externen Bibliothek:
public class Dog
{
    public string Name { get; set; }
    public List<DateTime> Vaccinations { get; set; } = new List<DateTime>();
}

// Erweiterungsklasse mit extension block:
public static class DogExtensions
{
    extension(Dog)
    {
        public bool AllVaccinatedThisYear
        {
            get => Vaccinations.Any(v => v.Year == DateTime.Now.Year);
        }
    }
}

// Im Programm:
var myDog = new Dog { Name = "Buddy" };
myDog.Vaccinations.Add(new DateTime(DateTime.Now.Year, 2, 16)); // Impfung dieses Jahr

Console.WriteLine($"{myDog.Name}: geimpft? {(myDog.AllVaccinatedThisYear ? "Ja" : "Nein")}");

7. Tabelle: Extension Methods vs Extension Properties

Extension Method Extension Property
Aufruf-Syntax obj.Method() obj.Property
Parameter übergeben Ja Nein (nur this obj)
Kann geschrieben werden Nicht anwendbar Nur wenn implementiert
Praktisch für View/UI Manchmal Ja (Two-way Bindings, Lambda)
Sichtbar in Reflection Nein Nein

8. Potenzielle Fallen und typische Fehler

Wann Extension Properties nicht helfen

  • Sie können keine echten Felder ersetzen: Sie haben keinen Zugriff auf private Members des Objekts.
  • Du kannst kein automatisches Ändern des Objektzustands hinzufügen (z.B. kannst du Wertänderungen im Original-Klasse nicht direkt berücksichtigen).
  • Du kannst Extension Properties nicht für die Implementierung eines Interface oder einer abstrakten Klasse nutzen.

Namenskonflikt-Fehler

Falls die Originalklasse plötzlich eine Property mit dem gleichen Namen wie deine bekommt, wird die „native“ Property benutzt, nicht deine Erweiterung. Sei also vorsichtig bei der Namenswahl, besonders bei öffentlichen .NET-Typen.

Probleme mit Serialisierung/Reflection

Extension Properties sind kein „echtes“ Member des Typs, sondern nur syntaktischer Zucker. Wenn irgendwo Reflection oder Serialisierung genutzt wird, kann die Extension Property für solche Tools unsichtbar sein.

2
Aufgabe
C# SELF, Level 18, Lektion 3
Gesperrt
Erstellung einer Erweiterungseigenschaft zur Überprüfung eines Schaltjahres
Erstellung einer Erweiterungseigenschaft zur Überprüfung eines Schaltjahres
2
Aufgabe
C# SELF, Level 18, Lektion 3
Gesperrt
Erstellung einer Erweiterungseigenschaft für einen String
Erstellung einer Erweiterungseigenschaft für einen String
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION