Freigeben über


Statische Klassen und Statische Klassenmitglieder (C#-Programmierhandbuch)

Eine statische Klasse ist im Grunde identisch mit einer nicht statischen Klasse, aber es gibt einen Unterschied: Eine statische Klasse kann nicht instanziiert werden. Mit anderen Worten, Sie können den neuen Operator nicht verwenden, um eine Variable des Klassentyps zu erstellen. Da keine Instanzvariable vorhanden ist, greifen Sie mithilfe des Klassennamens selbst auf die Member einer statischen Klasse zu. Wenn Sie beispielsweise eine statische Klasse haben, die eine öffentliche statische Methode mit dem Namen UtilityClassMethodAhat, rufen Sie die Methode auf, wie im folgenden Beispiel gezeigt:

UtilityClass.MethodA();

Eine statische Klasse kann als praktischer Container für Methodensätze verwendet werden, die nur für Eingabeparameter arbeiten und keine internen Instanzfelder abrufen oder festlegen müssen. Beispielsweise enthält die statische System.Math Klasse in der .NET-Klassenbibliothek Methoden, die mathematische Vorgänge ausführen, ohne dass Daten gespeichert oder abgerufen werden müssen, die für eine bestimmte Instanz der Math Klasse eindeutig sind. Das heißt, Sie wenden die Member der Klasse an, indem Sie den Klassennamen und den Methodennamen angeben, wie im folgenden Beispiel gezeigt.

double dub = -3.14;
Console.WriteLine(Math.Abs(dub));
Console.WriteLine(Math.Floor(dub));
Console.WriteLine(Math.Round(Math.Abs(dub)));

// Output:
// 3.14
// -4
// 3

Wie bei allen Klassentypen lädt die .NET-Laufzeit die Typinformationen für eine statische Klasse, wenn das Programm, das auf die Klasse verweist, geladen wird. Das Programm kann nicht genau angeben, wann die Klasse geladen wird. Es ist jedoch garantiert, dass die Felder geladen und der statische Konstruktor initialisiert wird, bevor die Klasse zum ersten Mal in Ihrem Programm referenziert wird. Ein statischer Konstruktor wird nur einmal aufgerufen, und eine statische Klasse bleibt für die Lebensdauer der Anwendungsdomäne, in der sich Ihr Programm befindet, im Arbeitsspeicher.

Hinweis

Informationen zum Erstellen einer nicht statischen Klasse, mit der nur eine Instanz selbst erstellt werden kann, finden Sie unter Implementieren von Singleton in C#.

Die folgende Liste enthält die Hauptmerkmale einer statischen Klasse:

  • Enthält nur statische Elemente.

  • Kann nicht instanziiert werden.

  • Ist versiegelt.

  • Instanzkonstruktoren können nicht enthalten sein.

Das Erstellen einer statischen Klasse entspricht daher im Grunde dem Erstellen einer Klasse, die nur statische Member und einen privaten Konstruktor enthält. Ein privater Konstruktor verhindert, dass die Klasse instanziiert wird. Der Vorteil der Verwendung einer statischen Klasse besteht darin, dass der Compiler überprüfen kann, um sicherzustellen, dass keine Instanzmember versehentlich hinzugefügt werden. Der Compiler garantiert, dass Instanzen dieser Klasse nicht erstellt werden können.

Statische Klassen sind versiegelt und können daher nicht geerbt werden. Sie können nicht von einer Klasse oder Schnittstelle erben, außer Object. Statische Klassen können keinen Instanzkonstruktor enthalten. Sie können jedoch einen statischen Konstruktor enthalten. Nicht statische Klassen sollten auch einen statischen Konstruktor definieren, wenn die Klasse statische Member enthält, die eine nicht triviale Initialisierung erfordern. Weitere Informationen finden Sie unter Statische Konstruktoren.

Beispiel

Hier ist ein Beispiel für eine statische Klasse, die zwei Methoden enthält, die Temperatur von Celsius in Fahrenheit und von Fahrenheit in Celsius umwandeln:

public static class TemperatureConverter
{
    public static double CelsiusToFahrenheit(string temperatureCelsius)
    {
        // Convert argument to double for calculations.
        double celsius = Double.Parse(temperatureCelsius);

        // Convert Celsius to Fahrenheit.
        double fahrenheit = (celsius * 9 / 5) + 32;

        return fahrenheit;
    }

    public static double FahrenheitToCelsius(string temperatureFahrenheit)
    {
        // Convert argument to double for calculations.
        double fahrenheit = Double.Parse(temperatureFahrenheit);

        // Convert Fahrenheit to Celsius.
        double celsius = (fahrenheit - 32) * 5 / 9;

        return celsius;
    }
}

class TestTemperatureConverter
{
    static void Main()
    {
        Console.WriteLine("Please select the convertor direction");
        Console.WriteLine("1. From Celsius to Fahrenheit.");
        Console.WriteLine("2. From Fahrenheit to Celsius.");
        Console.Write(":");

        string? selection = Console.ReadLine();
        double F, C = 0;

        switch (selection)
        {
            case "1":
                Console.Write("Please enter the Celsius temperature: ");
                F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine() ?? "0");
                Console.WriteLine($"Temperature in Fahrenheit: {F:F2}");
                break;

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0");
                Console.WriteLine($"Temperature in Celsius: {C:F2}");
                break;

            default:
                Console.WriteLine("Please select a convertor.");
                break;
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Example Output:
    Please select the convertor direction
    1. From Celsius to Fahrenheit.
    2. From Fahrenheit to Celsius.
    :2
    Please enter the Fahrenheit temperature: 20
    Temperature in Celsius: -6.67
    Press any key to exit.
 */

Statische Elemente

Eine nicht statische Klasse kann statische Methoden, Felder, Eigenschaften oder Ereignisse enthalten. Das statische Element kann für eine Klasse aufgerufen werden, auch wenn keine Instanz der Klasse vorhanden ist. Auf das statische Element wird immer über den Klassennamen und nicht über den Namen der Instanz zugegriffen. Es ist nur eine Kopie eines statischen Elements vorhanden, unabhängig davon, wie viele Instanzen der Klasse erstellt werden. Statische Methoden und Eigenschaften können nicht auf nicht statische Felder und Ereignisse in ihrem enthaltenden Typ zugreifen, und sie können nicht auf eine Instanzvariable eines Objekts zugreifen, es sei denn, sie wird explizit in einem Methodenparameter übergeben.

Es ist typischer, eine nicht statische Klasse mit einigen statischen Membern zu deklarieren, als eine gesamte Klasse als statisch zu deklarieren. Zwei häufige Verwendungen statischer Felder sind die Zählung der Anzahl der Objekte, die instanziiert werden, oder um einen Wert zu speichern, der für alle Instanzen freigegeben werden muss.

Statische Methoden können überladen, aber nicht außer Kraft gesetzt werden, da sie zur Klasse gehören, und nicht zu einer Instanz der Klasse.

Obwohl ein Feld nicht als static constdeklariert werden kann, ist ein Konstfeld im Wesentlichen statisch in seinem Verhalten. Sie gehört zum Typ, nicht zu Instanzen des Typs. Daher können auf const Felder mithilfe der gleichen ClassName.MemberName Schreibweise zugegriffen werden, die für statische Felder verwendet wird. Es ist keine Objektinstanz erforderlich.

C# unterstützt keine statischen lokalen Variablen (d. h. Variablen, die im Methodenbereich deklariert sind).

Sie deklarieren statische Klassenmember mithilfe des schlüsselworts static vor dem Rückgabetyp des Elements, wie im folgenden Beispiel gezeigt:

public class Automobile
{
    public static int NumberOfWheels = 4;

    public static int SizeOfGasTank
    {
        get
        {
            return 15;
        }
    }

    public static void Drive() { }

    public static event EventType? RunOutOfGas;

    // Other non-static fields and properties...
}

Statische Member werden initialisiert, bevor zum ersten Mal auf das statische Element zugegriffen wird und bevor der statische Konstruktor aufgerufen wird, falls vorhanden. Verwenden Sie für den Zugriff auf ein statisches Klassenelement den Namen der Klasse anstelle eines Variablennamens, um den Speicherort des Elements anzugeben, wie im folgenden Beispiel gezeigt:

Automobile.Drive();
int i = Automobile.NumberOfWheels;

Wenn Ihre Klasse statische Felder enthält, stellen Sie einen statischen Konstruktor bereit, der sie initialisiert, wenn die Klasse geladen wird.

Ein Aufruf einer statischen Methode generiert eine Aufrufanweisung in allgemeiner Zwischensprache (CIL), während ein Aufruf einer Instanzmethode eine callvirt Anweisung generiert, die auch auf NULL-Objektverweise überprüft. Die meiste Zeit ist der Leistungsunterschied zwischen den beiden jedoch nicht signifikant.

C#-Sprachspezifikation

Weitere Informationen finden Sie unter Statische Klassen, Static- und Instance-Member und Static-Konstruktoren in der C#-Sprachspezifikation. Die Sprachspezifikation ist die endgültige Quelle für C#-Syntax und -Verwendung.

Siehe auch