Statische Klassen und statische Klassenmember (C#-Programmierhandbuch)

Eine statische Klasse gleicht im Grunde einer nicht statischen Klasse, mit einem Unterschied: eine statische Klasse kann nicht instanziiert werden. In anderen Worten, Sie können das new-Schlüsselwort nicht verwenden, um eine Variable des Klassentyps zu erstellen. Da keine Instanzvariable vorhanden ist, greifen Sie auf die Member einer statischen Klasse mit dem Klassennamen selbst zu. Wenn Sie beispielsweise eine statische Klasse mit dem Namen UtilityClass haben, die über eine öffentliche Methode mit dem Namen MethodA verfügt, rufen Sie die Methode wie im folgenden Beispiel dargestellt auf:

UtilityClass.MethodA();

Eine statische Klasse kann als geeigneter Container für Sätze von Methoden verwendet werden, die nur mit Eingabeparametern arbeiten und die keine internen Instanzfelder abrufen oder festlegen müssen. In der .NET Framework-Klassenbibliothek enthält die statische System.Math-Klasse beispielsweise Methoden zur Durchführung mathematischer Operationen, ohne die Erfordernis zum Speichern oder Abrufen von Daten, die spezifisch für eine bestimmte Instanz der Math-Klasse sind. Das heißt, Sie wenden die Member der Klasse an, indem Sie den Klassennamen und den Methodennamen wie im folgenden Beispiel angeben.

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 werden die Typinformationen für eine statische Klasse von der CLR (Common Language Runtime) von .NET Framework geladen, wenn das Programm, das auf die Klasse verweist, geladen wird. Das Programm kann nicht genau festlegen, wann die Klasse geladen wird. Mit Bestimmtheit wird sie jedoch geladen, die zugehörigen Felder werden initialisiert und der statische Konstruktor wird aufgerufen, bevor im Programm zum ersten Mal auf die Klasse verwiesen wird. Ein statischer Konstruktor wird nur einmal aufgerufen, und eine statische Klasse verbleibt im Speicher für die Lebensdauer der Anwendungsdomäne, in der sich das Programm befindet.

Tipp

Informationen zum Erstellen einer nicht statischen Klasse, die nur die Erstellung einer einzigen Instanz von sich selbst zulässt, finden Sie unter Implementing Singleton in C#.

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

  • Enthält nur statische Member.

  • Kann nicht instanziiert werden.

  • Ist versiegelt.

  • Kann keine Instanzkonstruktoren enthalten.

Das Erstellen einer statischen Klasse entspricht daher im Wesentlichen 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 von statischen Klassen besteht darin, dass der Compiler eine Überprüfung ausführen und sicherstellen kann, dass nicht versehentlich Instanzmember hinzugefügt werden. Der Compiler garantiert, dass keine Instanzen dieser Klasse erstellt werden können.

Statische Klassen sind versiegelt und deshalb nicht vererbbar. Sie können von keiner Klasse erben, außer von Object. Statische Klassen können keinen Instanzkonstruktor enthalten, stattdessen jedoch einen statischen Konstruktor. 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 (C#-Programmierhandbuch).

Beispiel

Das folgende Beispiel einer statischen Klasse enthält zwei Methoden, die die Temperatur von Grad Celsius in Grad Fahrenheit und umgekehrt 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());
                    Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
                    break;

                case "2":
                    Console.Write("Please enter the Fahrenheit temperature: ");
                    C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());
                    Console.WriteLine("Temperature in Celsius: {0:F2}", C);
                    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 Member

Eine nicht statische Klasse kann statische Methoden, Felder, Eigenschaften oder Ereignisse enthalten. Der statische Member ist in einer Klasse auch dann aufrufbar, wenn keine Instanz der Klasse erstellt wurde. Auf den statischen Member wird immer anhand des Klassennamens anstelle des Instanznamens zugegriffen. Von einem statischen Member existiert nur eine Kopie, unabhängig davon, wie viele Instanzen der Klasse erstellt werden. Statische Methoden und Eigenschaften haben in ihrem enthaltenden Typ keinen Zugriff auf nicht statische Felder und Ereignisse, und sie können auf eine Instanzvariable eines Objekts nur zugreifen, wenn diese explizit in einem Methodenparameter übergeben wird.

Es kommt es häufiger vor, dass eine nicht statische Klasse mit ein paar statischen Membern deklariert wird, als dass eine gesamte Klasse als statisch deklariert wird. Das Zählen der Anzahl instanziierter Objekte oder das Speichern eines Werts, der für alle Instanzen freigegeben werden muss, sind zwei allgemeine Verwendungsweisen für statische Felder.

Statische Methoden können überladen, jedoch nicht überschrieben werden, da sie zur Klasse und nicht zu einer Instanz der Klasse gehören.

Obwohl ein Feld nicht als static const deklariert werden kann, ist ein const-Feld in seinem Verhalten im Wesentlichen statisch. Es gehört zum Typ und nicht zu Instanzen des Typs. Daher kann auf const-Felder mithilfe der gleichen ClassName.MemberName-Notation wie bei statischen Feldern zugegriffen werden. Eine Objektinstanz ist nicht erforderlich.

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

Statische Klassenmember werden mit dem static-Schlüsselwort vor dem Rückgabetyp des Members deklariert, wie im folgenden Beispiel erläutert:

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 vor dem ersten Zugriff auf den statischen Member und vor dem Aufruf des statischen Konstruktors, soweit vorhanden, initialisiert. Sie können auf einen statischen Klassenmember zugreifen, indem Sie anstelle eines Variablennamens den Klassennamen verwenden, um den Speicherort des Members anzugeben, wie im folgenden Beispiel erläutert:

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

Wenn die Klasse statische Felder enthält, geben Sie einen statischen Konstruktur an, der diese Felder beim Laden der Klasse initialisiert.

Ein Aufruf einer statischen Methode generiert in Microsoft Intermediate Language (MSIL) eine Aufrufanweisung, während ein Aufruf einer Instanzmethode eine callvirt-Anweisung generiert, bei der auch eine Überprüfung auf NULL-Objektverweise durchgeführt wird. Meistens ist der Leistungsunterschied zwischen beiden jedoch nicht spürbar.

C#-Programmiersprachenspezifikation

Weitere Informationen finden Sie in der C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

Referenz

static (C#-Referenz)

Klassen (C#-Programmierhandbuch)

class (C#-Referenz)

Statische Konstruktoren (C#-Programmierhandbuch)

Instanzkonstruktoren (C#-Programmierhandbuch)

Konzepte

C#-Programmierhandbuch

Entwurf statischer Klassen