Sdílet prostřednictvím


Statické třídy a členy statických tříd (Průvodce programováním v C#)

Statická třída je v podstatě stejná jako nestatická třída, ale existuje jeden rozdíl: statickou třídu nelze vytvořit instanci. Jinými slovy, nový operátor nemůžete použít k vytvoření proměnné typu třídy. Vzhledem k tomu, že neexistuje žádná proměnná instance, přistupujete k členům statické třídy pomocí samotného názvu třídy. Pokud máte například statickou třídu s názvem UtilityClass , která má veřejnou statickou metodu s názvem MethodA, zavoláte metodu, jak je znázorněno v následujícím příkladu:

UtilityClass.MethodA();

Statickou třídu lze použít jako pohodlný kontejner pro sady metod, které pouze pracují se vstupními parametry a nemusí získat ani nastavovat žádná interní pole instance. Například v knihovně tříd .NET obsahuje statická System.Math třída metody, které provádějí matematické operace, aniž by bylo nutné ukládat nebo načítat data, která jsou jedinečná pro konkrétní instanci Math třídy. To znamená, že použijete členy třídy zadáním názvu třídy a názvu metody, jak je znázorněno v následujícím příkladu.

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

Stejně jako u všech typů tříd modul runtime .NET načte informace o typu pro statickou třídu při načtení programu, který odkazuje na třídu. Program nemůže určit přesně, kdy je třída načtena. Je však zaručeno, že třída bude načtena, její pole inicializována a její statický konstruktor vyvolán před tím, než je třída ve vašem programu poprvé použita. Statický konstruktor se nazývá pouze jednou a statická třída zůstává v paměti po celou dobu životnosti domény aplikace, ve které se program nachází.

Poznámka:

Pokud chcete vytvořit nestatickou třídu, která umožňuje vytvoření pouze jedné její instance, přečtěte si téma Implementace Singletonu v jazyce C#.

Následující seznam obsahuje hlavní funkce statické třídy:

  • Obsahuje pouze statické členy.

  • Nelze vytvořit instanci.

  • Je zapečetěný.

  • Nelze obsahovat konstruktory instance.

Vytvoření statické třídy je tedy v podstatě stejné jako vytvoření třídy, která obsahuje pouze statické členy a privátní konstruktor. Privátní konstruktor zabraňuje instanciování třídy. Výhodou použití statické třídy je, že kompilátor může zkontrolovat, zda nejsou náhodně přidány žádné členy instance. Kompilátor zaručuje, že instance této třídy nelze vytvořit.

Statické třídy jsou zapečetěné, a proto je nelze zdědit. Nemůžou dědit z žádné třídy nebo rozhraní s výjimkou Object. Statické třídy nemohou obsahovat konstruktor instance. Mohou však obsahovat statický konstruktor. Nestatické třídy by také měly definovat statický konstruktor, pokud třída obsahuje statické členy, které vyžadují ne triviální inicializaci. Další informace naleznete v tématu statické konstruktory.

Příklad

Tady je příklad statické třídy, která obsahuje dvě metody, které převádějí teplotu ze stupně Celsia na Fahrenheita a Fahrenheita na stupně Celsia:

public static class TemperatureConverter
{
    public static double CelsiusToFahrenheit(string temperatureCelsius) =>
        double.Parse(temperatureCelsius) * 9 / 5 + 32;

    public static double FahrenheitToCelsius(string temperatureFahrenheit) =>
        (double.Parse(temperatureFahrenheit) - 32) * 5 / 9;
}

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();

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

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                var 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.
 */

Statické členy

Nestatická třída může obsahovat statické metody, pole, vlastnosti nebo události. Statický člen je volán pro třídu, i když neexistuje žádná instance třídy. Statický člen je vždy přístupný názvem třídy, nikoli názvem instance. Existuje pouze jedna kopie statického členu bez ohledu na to, kolik instancí třídy je vytvořeno. U obecných typů má každý uzavřený obecný typ vlastní kopii statických členů. Statická pole označená ThreadStaticAttribute mají jednu kopii na vlákno. Statické metody a členy nemají přístup k nestatickým polím a událostem v jejich typu, a nemohou získat přístup k proměnným instance jakéhokoli objektu, pokud nejsou explicitně předány jako parametr metody.

Je typičtější deklarovat nestatickou třídu se statickými členy, než deklarovat celou třídu jako statickou. Dvě běžná použití statických polí jsou uchování počtu objektů, které byly instanciovány, nebo uložení hodnoty, která se musí sdílet mezi všemi instancemi.

Statické metody lze přetížit, ale nelze je přepsat, protože patří přímo třídě, nikoliv instanci třídy.

I když pole nelze deklarovat jako static const, pole const je v podstatě statické ve svém chování. Patří k typu, nikoli k instancím typu. K const polím je proto možné přistupovat pomocí stejného ClassName.MemberName zápisu, který se používá pro statická pole. Není vyžadována žádná instance objektu.

Jazyk C# nepodporuje statické místní proměnné (to znamená proměnné deklarované v oboru metody).

Statické členy třídy deklarujete pomocí klíčového slova static před návratovým typem členu, jak je znázorněno v následujícím příkladu:

public class Automobile
{
    public static int NumberOfWheels = 4;

    public static int SizeOfGasTank => 15;

    public static void Drive() { }

    public static event EventType? RunOutOfGas;

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

Statické členy jsou inicializovány před prvním přístupem ke statickému členu a před voláním statického konstruktora, pokud nějaký existuje. Pokud chcete získat přístup ke statickému členu třídy, použijte místo názvu proměnné název člena, jak je znázorněno v následujícím příkladu:

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

Pokud vaše třída obsahuje statická pole, zadejte statický konstruktor, který je inicializuje při načtení třídy.

Volání statické metody generuje instrukci volání v obyčejném mezilehlém jazyce (CIL), zatímco volání metody instance generuje instrukci, která také kontroluje odkazy na null objekt. Ve většině případů ale rozdíl mezi výkonem mezi těmito dvěma není významný.

Specifikace jazyka C#

Další informace naleznete v tématu Statické třídy, Statické a instanční členy a Statické konstruktory ve specifikaci jazyka C#. Specifikace jazyka je konečným zdrojem syntaxe a použití jazyka C#.

Viz také