Statiska klasser och statiska klassmedlemmar (C#-programmeringsguide)

En statisk klass är i princip samma som en icke-statisk klass, men det finns en skillnad: en statisk klass kan inte instansieras. Med andra ord kan du inte använda den nya operatorn för att skapa en variabel av klasstypen. Eftersom det inte finns någon instansvariabel får du åtkomst till medlemmarna i en statisk klass med hjälp av själva klassnamnet. Om du till exempel har en statisk klass med namnet UtilityClass som har en offentlig statisk metod med namnet MethodAanropar du metoden enligt följande exempel:

UtilityClass.MethodA();

En statisk klass kan användas som en praktisk container för uppsättningar med metoder som bara fungerar på indataparametrar och inte behöver hämta eller ange några interna instansfält. I .NET-klassbiblioteket innehåller den statiska System.Math klassen till exempel metoder som utför matematiska åtgärder, utan krav på att lagra eller hämta data som är unika för en viss instans av Math klassen. Det vill säga att du tillämpar medlemmarna i klassen genom att ange klassnamnet och metodnamnet, som du ser i följande exempel.

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

Precis som med alla klasstyper läser .NET-körningen in typinformationen för en statisk klass när programmet som refererar till klassen läses in. Programmet kan inte ange exakt när klassen läses in. Det är dock garanterat att läsa in och få dess fält initierade och dess statiska konstruktor anropas innan klassen refereras för första gången i ditt program. En statisk konstruktor anropas bara en gång och en statisk klass finns kvar i minnet under hela programdomänen där programmet finns.

Kommentar

Information om hur du skapar en icke-statisk klass som endast tillåter att en instans av sig själv skapas finns i Implementera Singleton i C#.

Följande lista innehåller huvudfunktionerna i en statisk klass:

  • Innehåller endast statiska medlemmar.

  • Det går inte att instansiera.

  • Är förseglad.

  • Det går inte att innehålla instanskonstruktorer.

Att skapa en statisk klass är därför i princip detsamma som att skapa en klass som endast innehåller statiska medlemmar och en privat konstruktor. En privat konstruktor förhindrar att klassen instansieras. Fördelen med att använda en statisk klass är att kompilatorn kan kontrollera att inga instansmedlemmar läggs till av misstag. Kompilatorn garanterar att instanser av den här klassen inte kan skapas.

Statiska klasser är förseglade och kan därför inte ärvas. De kan inte ärva från någon klass eller ett gränssnitt förutom Object. Statiska klasser får inte innehålla en instanskonstruktor. De kan dock innehålla en statisk konstruktor. Icke-statiska klasser bör också definiera en statisk konstruktor om klassen innehåller statiska medlemmar som kräver icke-trivial initiering. Mer information finns i Statiska konstruktorer.

Exempel

Här är ett exempel på en statisk klass som innehåller två metoder som konverterar temperatur från Celsius till Fahrenheit och från Fahrenheit till Celsius:

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.
 */

Statiska medlemmar

En icke-statisk klass kan innehålla statiska metoder, fält, egenskaper eller händelser. Den statiska medlemmen kan anropas för en klass även om det inte finns någon instans av klassen. Den statiska medlemmen används alltid av klassnamnet, inte instansnamnet. Det finns bara en kopia av en statisk medlem, oavsett hur många instanser av klassen som skapas. Statiska metoder och egenskaper kan inte komma åt icke-statiska fält och händelser i deras innehållande typ, och de kan inte komma åt en instansvariabel för något objekt om det inte uttryckligen skickas i en metodparameter.

Det är mer typiskt att deklarera en icke-statisk klass med vissa statiska medlemmar än att deklarera en hel klass som statisk. Två vanliga användningsområden för statiska fält är att behålla antalet objekt som instansieras eller för att lagra ett värde som måste delas mellan alla instanser.

Statiska metoder kan överbelastas men inte åsidosättas eftersom de tillhör klassen och inte till någon instans av klassen.

Även om ett fält inte kan deklareras som static const, är ett const-fält i stort sett statiskt i sitt beteende. Den tillhör typen, inte instanser av typen. Därför const kan du komma åt fält med samma ClassName.MemberName notation som används för statiska fält. Ingen objektinstans krävs.

C# stöder inte statiska lokala variabler (d.v.s. variabler som deklareras i metodomfånget).

Du deklarerar statiska klassmedlemmar med hjälp av nyckelordet static före medlemmens returtyp, som du ser i följande exempel:

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...
}

Statiska medlemmar initieras innan den statiska medlemmen används för första gången och innan den statiska konstruktorn, om det finns en, anropas. Om du vill komma åt en statisk klassmedlem använder du namnet på klassen i stället för ett variabelnamn för att ange medlemmens plats, som du ser i följande exempel:

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

Om klassen innehåller statiska fält anger du en statisk konstruktor som initierar dem när klassen läses in.

Ett anrop till en statisk metod genererar en anropsinstruktion på det gemensamma mellanliggande språket (CIL), medan ett anrop till en instansmetod genererar en callvirt instruktion som även söker efter null-objektreferenser. Men för det mesta är prestandaskillnaden mellan de två inte betydande.

Språkspecifikation för C#

Mer information finns i Statiska klasser, Statiska och instansmedlemmar och Statiska konstruktorer i C#-språkspecifikationen. Språkspecifikationen är den slutgiltiga källan för C#-syntax och -användning.

Se även