Menu

C# static: statische Klassen, Methoden, Felder und Konstruktoren

Was static in C# bedeutet: Member, die zum Typ statt zu einem Objekt gehören, über Instanzen geteilter Zustand, statische Methoden und statische Klassen, statische Konstruktoren, const vs. static readonly, using static und der Fehler CS0120.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

static kennzeichnet einen Member, der zum Typ gehört, nicht zu einem Objekt. Ein Instanzfeld existiert einmal pro Objekt; ein statisches Feld existiert einmal, Punkt. Eine Instanzmethode läuft auf einem Objekt (order.Ship()); eine statische Methode läuft auf dem Typ (Math.Round(x)) und braucht überhaupt kein Objekt.

Statische Felder: eine Kopie, geteilt

Am klarsten zeigt ein Zähler den Unterschied. Jede Order hat ihre eigene Id, aber die Anzahl der bisher erzeugten Bestellungen muss an einem gemeinsamen Ort liegen.

Ausgabe:

Ana #1, Ben #2, Chen #3
Orders created: 3

Auf statische Member wird über den Typnamen zugegriffen: Order.Created, nicht a.Created. C# erlaubt es nicht, einen statischen Member über eine Instanz zu erreichen (Fehler CS0176), was an der Aufrufstelle deutlich macht, dass der Wert geteilt ist.

Statische Methoden

Eine statische Methode hat kein this. Sie arbeitet nur mit ihren Parametern und anderen statischen Membern. Das macht sie zur natürlichen Form für Hilfsmethoden, die etwas aus ihren Eingaben berechnen:

Ausgabe:

61.38 EUR
7

Main selbst ist statisch: Die Runtime ruft es auf, bevor irgendein Objekt existiert.

Der Fehler CS0120: statischer Code verwendet Instanzmember

Weil Main statisch ist, stoßen Einsteiger auf diesen Fehler, sobald sie eine zweite Methode hinzufügen:

class Program
{
    int visits;
    void Greet() { Console.WriteLine("Hello"); }

    static void Main()
    {
        Greet();    // error CS0120: An object reference is required for the non-static field, method, or property 'Program.Greet()'
        visits++;   // error CS0120: An object reference is required for the non-static field, method, or property 'Program.visits'
    }
}

Eine statische Methode hat kein Objekt, es gibt also kein visits, das sie erhöhen könnte. Zwei Lösungen, und die richtige hängt davon ab, was der Member ist:

  • Der Member sind wirklich Daten pro Objekt: Erzeuge ein Objekt und verwende es. var app = new Program(); app.Greet();
  • Der Member braucht keinen Objektzustand: Markiere ihn als static. static void Greet() { ... }

Alles als static zu markieren, damit der Fehler verschwindet, funktioniert in einem winzigen Programm und wird in einem echten zu globalem Zustand. Entscheide anhand der Frage, ob die Daten zu einem Objekt oder zum ganzen Programm gehören.

Die umgekehrte Richtung ist immer erlaubt: Instanzmethoden können statische Member frei aufrufen.

Statische Klassen

Eine als static deklarierte Klasse darf nur statische Member enthalten und kann nie instanziiert werden. Sie ist eine benannte Gruppe von Funktionen und Konstanten.

Ausgabe:

77
100
True

Der Compiler setzt den Vertrag durch: Ein Instanzmember in einer statischen Klasse ist Fehler CS0708, und new darauf ist Fehler CS0712. Math, Console, File, Path und Enumerable sind alle statische Klassen. Auch Erweiterungsmethoden müssen in einer statischen Klasse stehen.

Statische Konstruktoren und static readonly

Ein statisches Feld, dessen Wert mehr als einen Ausdruck braucht, kann in einem statischen Konstruktor gesetzt werden, den die Runtime einmal ausführt, bevor der Typ zum ersten Mal verwendet wird:

Ausgabe:

Before first use
ShippingRates initialized
5.50
3
2026-01-01

readonly bedeutet, dass das Feld nur in seinem Initialisierer oder im statischen Konstruktor zugewiesen werden kann. Danach lässt es sich nicht neu zuweisen, auch wenn das Objekt, auf das es zeigt, noch veränderlich sein könnte, deshalb wird das Dictionary als IReadOnlyDictionary bereitgestellt.

const gegenüber static readonly

Beide geben dir einen benannten Wert, den das ganze Programm teilt, und sie unterscheiden sich darin, wann der Wert feststeht:

conststatic readonly
Wert steht festzur Kompilierzeitzur Laufzeit, einmalig
Erlaubte TypenZahlen, char, bool, string, Enums, nulljeder Typ
Implizit statischja (static const ist nicht erlaubt)explizit als static deklariert
In aufrufende Assemblies kopiertjanein, wird aus dem Feld gelesen
In switch-Fällen und Attributargumenten verwendbarjanein

Die Zeile zum Kopieren zählt bei Bibliotheken: Deklariert Assembly A public const int MaxItems = 50; und verwendet Assembly B das, enthält B das Literal 50. A auf 100 zu ändern bewirkt für B nichts, bis B neu kompiliert wird. Für Werte, die sich zwischen Versionen ändern könnten, nimm lieber static readonly.

using static

Eine using static-Direktive (C# 6) importiert die statischen Member eines Typs, sodass du sie ohne den Typnamen aufrufen kannst:

Ausgabe:

Area: 28.27
40

Bei mathelastigem Code liest sich das gut. Anderswo nimm es sparsam: Ein nacktes WriteLine oder Parse verbirgt, von welchem Typ die Methode kommt.

Statischer Zustand und Threads

Ein statisches Feld wird von jedem Thread im Prozess geteilt. Es aus mehreren Threads gleichzeitig zu erhöhen verliert Aktualisierungen, weil created++ ein Lesen, ein Addieren und ein Schreiben ist und zwei Threads diese verschränken können. Nimm Interlocked.Increment(ref created) für Zähler oder einen Lock für alles Größere. Webanwendungen sind der übliche Ort, an dem das zubeißt: Jede Anfrage läuft auf irgendeinem Thread, ein statisches Feld mit „dem aktuellen Benutzer“ wird also von allen Benutzern geteilt.

Noch eine Feinheit: In einer generischen Klasse bekommt jeder konstruierte Typ seine eigenen statischen Felder. Cache<int>.Count und Cache<string>.Count sind zwei verschiedene Felder.

Wann static passt

Gute Einsätze:

  • Reine Hilfsmethoden, die ein Ergebnis aus ihren Argumenten berechnen: Formatierung, Umwandlungen, Validierung.
  • Konstanten und schreibgeschützte Nachschlagedaten, die das Programm teilt.
  • Fabrikmethoden wie TimeSpan.FromMinutes(5) oder dein eigenes Temperature.FromCelsius(21).
  • Erweiterungsmethoden.

Schlechte Einsätze:

  • Veränderlicher globaler Zustand (der aktuelle Benutzer, ein Warenkorb, Einstellungen, die sich ändern). Er koppelt jedes Codestück, das ihn berührt, und macht Tests von den Überbleibseln anderer Tests abhängig.
  • Alles, was du in Tests austauschen willst, etwa eine Uhr, eine Datenbank oder einen E-Mail-Versender. Statische Aufrufe lassen sich nicht durch eine Attrappe ersetzen; eine an den Konstruktor übergebene Instanz schon.

Häufig gestellte Fragen

Was bedeutet static in C#?

Ein static-Member gehört zum Typ selbst statt zu einem Objekt. Von einem statischen Feld gibt es genau eine Kopie, egal wie viele Objekte existieren, und eine statische Methode wird über den Typnamen aufgerufen (Math.Max(3, 7)), ohne eine Instanz zu erzeugen. Eine statische Methode hat kein this und kann daher Instanzfelder nicht direkt verwenden.

Was ist eine statische Klasse in C#?

Eine als static deklarierte Klasse kann nur statische Member enthalten und nie instanziiert werden (new darauf ist Fehler CS0712). Sie gruppiert zusammengehörige Funktionen, die keinen Objektzustand brauchen, wie Math, Console oder File. Erweiterungsmethoden müssen in einer statischen Klasse deklariert werden.

Wie behebe ich „An object reference is required for the non-static field, method, or property“?

Das ist Fehler CS0120: Eine statische Methode, oft Main, verwendet einen Instanzmember. Erzeuge entweder ein Objekt und rufe den Member darauf auf (var app = new Program(); app.Run();) oder markiere den Member als static, wenn er keine Daten pro Objekt braucht.

Was ist der Unterschied zwischen const und static readonly in C#?

Ein const ist eine Konstante zur Kompilierzeit (Zahlen, Strings, bool, Enums), deren Wert in jede Assembly kopiert wird, die ihn verwendet. Ein static readonly-Feld wird einmal zur Laufzeit zugewiesen, in seinem Initialisierer oder im statischen Konstruktor, und kann jeden Typ enthalten, etwa ein DateTime oder eine Liste. Nimm const für Werte, die sich nie ändern, und static readonly für alles andere.

Wann sollte ich in C# static verwenden?

Nimm static für Code, der nur mit seinen Parametern arbeitet (reine Hilfsmethoden wie ein Preisformatierer), für Konstanten und Caches, die wirklich global für das Programm sind, und für Fabrikmethoden. Vermeide static für alles, was Zustand pro Benutzer oder pro Anfrage hält oder was du in Tests austauschen willst: Geteilter veränderlicher Zustand ist schwer zu testen und ohne Locking nicht threadsicher.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S