Statische klassen en statische klasseleden (C#-programmeerhandleiding)

Een statische klasse is in feite hetzelfde als een niet-statische klasse, maar er is één verschil: een statische klasse kan niet worden geïnstantieerd. Met andere woorden, u kunt de nieuwe operator niet gebruiken om een variabele van het klassetype te maken. Omdat er geen exemplaarvariabele is, opent u de leden van een statische klasse met behulp van de klassenaam zelf. Als u bijvoorbeeld een statische klasse hebt met een benoemde UtilityClass openbare statische methode MethodA, roept u de methode aan, zoals wordt weergegeven in het volgende voorbeeld:

UtilityClass.MethodA();

Een statische klasse kan worden gebruikt als een handige container voor sets methoden die alleen op invoerparameters werken en geen interne exemplaarvelden hoeven op te halen of in te stellen. In de .NET-klassebibliotheek bevat de statische System.Math klasse bijvoorbeeld methoden die wiskundige bewerkingen uitvoeren, zonder dat u gegevens hoeft op te slaan of op te halen die uniek zijn voor een bepaald exemplaar van de Math klasse. Dat wil gezegd: u past de leden van de klasse toe door de klassenaam en de naam van de methode op te geven, zoals wordt weergegeven in het volgende voorbeeld.

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

Net als bij alle klassetypen laadt de .NET-runtime de typegegevens voor een statische klasse wanneer het programma dat naar de klasse verwijst, wordt geladen. Het programma kan niet exact opgeven wanneer de klasse wordt geladen. Het is echter gegarandeerd dat de velden worden geladen en de velden worden geïnitialiseerd en de statische constructor die wordt aangeroepen voordat de klasse voor het eerst in uw programma wordt verwezen. Een statische constructor wordt slechts één keer aangeroepen en een statische klasse blijft gedurende de levensduur van het toepassingsdomein waarin uw programma zich bevindt, in het geheugen.

Notitie

Zie Singleton implementeren in C# als u een niet-statische klasse wilt maken waarmee slechts één exemplaar van zichzelf kan worden gemaakt.

De volgende lijst bevat de belangrijkste functies van een statische klasse:

  • Bevat alleen statische leden.

  • Kan niet geïnstantieerd worden.

  • Is verzegeld.

  • Kan geen exemplaarconstructors bevatten.

Het maken van een statische klasse is daarom in principe hetzelfde als het maken van een klasse die alleen statische leden en een privéconstructor bevat. Een privéconstructor voorkomt dat de klasse wordt geïnstantieerd. Het voordeel van het gebruik van een statische klasse is dat de compiler kan controleren of er geen exemplaarleden per ongeluk worden toegevoegd. De compiler garandeert dat exemplaren van deze klasse niet kunnen worden gemaakt.

Statische klassen worden verzegeld en kunnen daarom niet worden overgenomen. Ze kunnen niet overnemen van een klasse of interface, behalve Object. Statische klassen kunnen geen exemplaarconstructor bevatten. Ze kunnen echter een statische constructor bevatten. Niet-statische klassen moeten ook een statische constructor definiëren als de klasse statische leden bevat waarvoor niet-triviale initialisatie is vereist. Zie Statische constructors voor meer informatie.

Opmerking

Hier volgt een voorbeeld van een statische klasse die twee methoden bevat waarmee de temperatuur van Celsius naar Fahrenheit en van Fahrenheit naar Celsius wordt geconverteerd:

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: {0:F2}", F);
                break;

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0");
                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 leden

Een niet-statische klasse kan statische methoden, velden, eigenschappen of gebeurtenissen bevatten. Het statische lid kan worden aangeroepen voor een klasse, zelfs wanneer er geen exemplaar van de klasse bestaat. Het statische lid wordt altijd geopend door de klassenaam, niet de exemplaarnaam. Er bestaat slechts één kopie van een statisch lid, ongeacht het aantal exemplaren van de klasse. Statische methoden en eigenschappen hebben geen toegang tot niet-statische velden en gebeurtenissen in het bijbehorende type en ze hebben geen toegang tot een exemplaarvariabele van een object, tenzij deze expliciet wordt doorgegeven in een methodeparameter.

Het is gebruikelijker om een niet-statische klasse met een aantal statische leden te declareren dan om een hele klasse als statisch te declareren. Twee veelvoorkomende toepassingen van statische velden zijn het bijhouden van het aantal objecten dat wordt geïnstantieerd of om een waarde op te slaan die moet worden gedeeld tussen alle exemplaren.

Statische methoden kunnen worden overbelast, maar niet worden overschreven, omdat ze deel uitmaken van de klasse en niet van een exemplaar van de klasse.

Hoewel een veld niet kan worden gedeclareerd als static const, is een const-veld in wezen statisch in het gedrag ervan. Het behoort tot het type, niet tot exemplaren van het type. const Daarom kunnen velden worden geopend met behulp van dezelfde ClassName.MemberName notatie die wordt gebruikt voor statische velden. Er is geen objectexemplaren vereist.

C# biedt geen ondersteuning voor statische lokale variabelen (dat wil gezegd, variabelen die in het methodebereik worden gedeclareerd).

U declareert statische klasseleden met behulp van het static trefwoord voor het retourtype van het lid, zoals wordt weergegeven in het volgende voorbeeld:

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 leden worden geïnitialiseerd voordat het statische lid voor het eerst wordt geopend en voordat de statische constructor, als er een is, wordt aangeroepen. Als u toegang wilt krijgen tot een statisch klasselid, gebruikt u de naam van de klasse in plaats van een variabelenaam om de locatie van het lid op te geven, zoals wordt weergegeven in het volgende voorbeeld:

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

Als uw klasse statische velden bevat, geeft u een statische constructor op waarmee deze worden geïnitialiseerd wanneer de klasse wordt geladen.

Een aanroep naar een statische methode genereert een aanroepinstructie in algemene tussenliggende taal (CIL), terwijl een aanroep naar een instantiemethode een callvirt instructie genereert, waarmee ook wordt gecontroleerd op null-objectverwijzingen. Meestal is het prestatieverschil tussen de twee echter niet significant.

C#-taalspecificatie

Zie statische klassen, leden van statische en exemplaren en statische constructors in de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik.

Zie ook