CodeGym /Kurse /C# SELF /Statische Member in Interfaces

Statische Member in Interfaces

C# SELF
Level 24 , Lektion 1
Verfügbar

1. Einführung

Früher waren Interfaces streng wie das Regelwerk einer Privatschule: nur Signaturen, keine Felder, keine Implementierung, keine statischen Member! Aber .NET entwickelt sich weiter und eine Programmiersprache ist wie ein lebender Organismus: Um auf neue Herausforderungen zu reagieren, muss sie sich weiterentwickeln.

Mit den neuen Versionen von C# haben Interfaces ein paar neue Tricks gelernt. Einer der auffälligsten: statische Member in Interfaces. Es stellt sich heraus, dass Interfaces jetzt statische Methoden, Properties und Events enthalten können. In den neuen Versionen von C# (ab C# 11) gibt es sogar die Möglichkeit, statische abstrakte Methoden zu deklarieren, die eine Implementierung in den Typen verlangen, die dieses Interface implementieren.

Das ist ein riesiger Paradigmenwechsel, der den Ansatz für generische und objektorientierte Programmierung verändert.

Einfach gesagt: ein statisches Interface-Member ist ein "gemeinsames" Member, auf das man über den Interface-Typ selbst (oder über den implementierenden Typ) zugreift, nicht über eine Instanz.

Bis vor kurzem konnten nur Klassen, Structs und Enums statische Methoden und Properties haben, aber jetzt geht das auch mit Interfaces.

Wie sieht das aus? Beispiel-Syntax


public interface IMyMath
{
    static int Add(int a, int b) => a + b; // Statische Methode (Default-Implementierung)

    static abstract int Multiply(int a, int b); // Muss vom implementierenden Typ implementiert werden
}
  • static — Member ist auf Typ-Ebene verfügbar, nicht auf Instanz-Ebene.
  • static abstract — Verträge "verlangen", dass der statische Member im implementierenden Typ implementiert wird.
  • In Interfaces (wie auch in Klassen) kann man jetzt statische Methoden, Properties und Events deklarieren. Man kann auch Konstanten erstellen. Aber Interfaces dürfen immer noch keine Instanzfelder oder statische Felder (außer Konstanten) haben.

Der Sinn von statischen Membern in Interfaces ist, universelle "Operationen" deklarieren zu können. Zum Beispiel: Wenn du eine Sammlung von Objekten hast und für sie ein "Vergleich" aufrufen willst, ohne zu wissen, welcher Typ das Interface implementiert, geht das jetzt mit statischen abstrakten Membern.

2. Statische Methoden mit Implementierung im Interface

Wofür braucht man das überhaupt?

Das klassische Problem: Du willst nicht nur "Instanz"-Methoden beschreiben (z.B. etwas mit einem Objekt machen können), sondern auch "statische" (z.B. ein neues Objekt aus einem String erstellen oder zwei Objekte statisch vergleichen). Früher musste man das mit Patterns wie Factory, Comparer, Helper lösen, aber jetzt kann man das direkt im Interface ausdrücken.

Gerade für Generics und Algorithmen, die mit beliebigen Typen arbeiten, ist das super wichtig:

  • Implementierung von universellen Operatoren (z.B. Addition, Vergleich).
  • Einschränkung von generischem Code: "Alle Typen, die eine statische Methode oder einen Operator haben…"
  • Serialisierung/Deserialisierung: Wenn man ein Objekt aus einem String erstellen muss, ohne den Typ beim Schreiben des Codes zu kennen.

Statische Methoden mit Body

Seit C# 8 sind statische Methoden mit Body in Interfaces erlaubt. Sie sind wie normale statische Methoden in einer Klasse.


public interface IUtility
{
    static void PrintHello()
    {
        Console.WriteLine("Hallo vom Interface!");
    }
}

So eine Methode kann man so aufrufen: IUtility.PrintHello();

Das ist praktisch für Hilfsfunktionen, die logisch zum Interface gehören, aber nicht zu einer bestimmten Implementierung. Zum Beispiel: Statistik für alle Objekte eines Typs, Factory-Methoden (CreateDefault), allgemeine Checks (z.B. auf gültige Werte).

Besonderheit: Statische Interface-Member werden in Klassen nicht "überschrieben"

Wenn du im Interface static void Method() { ... } deklarierst, kann die implementierende Klasse eine gleichnamige statische Methode mit derselben Signatur deklarieren — aber das ist kein Überschreiben! Das sind einfach zwei unabhängige Methoden — der Name ist gleich, aber es ist keine "virtuelle statische Methode".

3. Statische abstrakte Member

Ab C# 11 darf man in Interfaces static abstract Methoden deklarieren. Das heißt: "Jede Klasse oder Struct, die dieses Interface implementiert, muss einen statischen Member mit derselben Signatur deklarieren".

Beispiel:


public interface IParsable<T>
{
    static abstract T Parse(string s);
}

Jeder Typ, der dieses Interface implementiert, muss die statische Methode Parse(string s) deklarieren.

Implementierung dieses Interfaces in einer Klasse


public class Temperature : IParsable<Temperature>
{
    public int Value { get; set; }

    // Statische Implementierung!
    public static Temperature Parse(string s)
    {
        var temp = new Temperature();
        temp.Value = int.Parse(s);
        return temp;
    }
}

Wie funktioniert das?

Das wird besonders spannend im generischen Code (Generics):


public static T ParseFromString<T>(string s) where T : IParsable<T>
{
    return T.Parse(s);
}

// Verwendung:
var temp = ParseFromString<Temperature>("42");

Jetzt kann man wirklich universellen Code schreiben, der mit allen Typen funktioniert, die "statisches" Verhalten implementieren!

4. Statische Member in Interfaces vs. normale statische Member in Klassen

Eigenschaft Statisches Klassen-Member Statisches Interface-Member
Wird vererbt Nein Nein, aber wird im Rahmen des Interface-Vertrags implementiert
Erfordert Implementierung Nein Nur wenn static abstract
Verwendbar in Generics Nein (bis C# 11) Ja (mit static abstract)
Kann Default-Implementierung haben Ja Ja
Überschreiben Nein Nein, nur Implementierung ist Pflicht
Sichtbarkeit beim Aufruf Über den Typnamen Über den Interface-Typ oder den implementierenden Typ

7. Beispiele aus der echten Welt

Schauen wir uns an, wie wir unsere kleine Lern-App mit den neuen Features verbessern können.

Angenommen, wir haben ein Interface "IPrintable":


public interface IPrintable
{
    void Print();
    static void PrintAll(IEnumerable<IPrintable> items)
    {
        foreach (var item in items)
        {
            item.Print();
        }
    }
}

Jetzt kann man bequem aufrufen:


var documents = new List<IPrintable>
{
    new Invoice { Number = "INV-001" },
    new Receipt { Number = "RC-007" }
};
IPrintable.PrintAll(documents); // statische Interface-Methode!

So eine Architektur ist super für "Gruppen"-Operationen auf allen Implementierungen eines Interfaces.

Fortgeschritteneres Beispiel: Generische Addition von Zahlentypen

Angenommen, wir haben ein Interface:


public interface IAddable<T>
{
    static abstract T Add(T left, T right);
}

Implementierung für ganze Zahlen (Wrapper-Klasse):


public struct MyInt : IAddable<MyInt>
{
    public int Value { get; }
    public MyInt(int val) => Value = val;
    public static MyInt Add(MyInt left, MyInt right) => new MyInt(left.Value + right.Value);
}

Und schließlich eine universelle Funktion zum Addieren von zwei Zahlen vom Typ T:


public static T Sum<T>(T a, T b) where T : IAddable<T>
{
    return T.Add(a, b);
}

// Verwendung:
var x = new MyInt(5);
var y = new MyInt(6);
var z = Sum(x, y); // z.Value == 11

Genau für solche Universalität wurde die Unterstützung für statische Member in Interfaces eingeführt!

8. Typische Fehler und Besonderheiten

Das Leben mit neuen Features ist nicht immer so einfach wie in den Beispielen. Hier ein paar Dinge, die Anfänger verwirren können:

Statische Interface-Methoden werden nicht vom implementierenden Typ "geerbt". Wenn du im Interface static void Foo() deklarierst, dann sind MyClass.Foo() und IMyInterface.Foo() zwei komplett verschiedene Methoden.

Static abstract muss implementiert werden. Wenn du das vergisst, meckert der Compiler, dass die Klasse das Interface nicht vollständig implementiert.

Generic constraints: Um statische abstrakte Member zu nutzen, musst du in den Generic-Parametern auf das Interface einschränken (where T : IMyInterface).

Nicht alle Tools unterstützen die neuen Features schon. Zum Beispiel Rider, VS Code oder alte Roslyn-Analyser zeigen static abstract-Member in Interfaces nicht immer korrekt an, wenn die .NET-Version kein C# 11+ unterstützt.

Nicht verwechseln mit Extension-Methoden für Interfaces: Die werden separat implementiert und funktionieren nicht wie statische Member.

2
Aufgabe
C# SELF, Level 24, Lektion 1
Gesperrt
Erstellung einer statischen Methode in einem Interface
Erstellung einer statischen Methode in einem Interface
2
Aufgabe
C# SELF, Level 24, Lektion 1
Gesperrt
Statische Methode mit Interface
Statische Methode mit Interface
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION