Statické třídy a jejich členové (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. Jinými slovy, operátor New nelze použít k vytvoření proměnné typu třídy. Vzhledem k tomu, že není k dispozici žádná proměnná instance, získáte přístup ke členům statické třídy pomocí samotného názvu třídy. Například pokud máte 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é fungují pouze na vstupních parametrech a nemusejí získávat ani nastavovat žádná interní pole instance. Například v knihovně tříd .NET statická System.Math Třída obsahuje metody, které provádějí matematické operace bez nutnosti 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 jsou informace o typu statické třídy načteny modulem runtime .NET, když je načten program, který odkazuje na třídu. Program nemůže přesně určovat, kdy je třída načtena. Je však zaručeno, že bude načteno a že jeho pole jsou inicializována a jeho statický konstruktor byl volán před tím, než je třída poprvé odkazována v programu. Statický konstruktor se volá jenom jednou a statická třída zůstane v paměti po dobu života domény aplikace, ve které se váš program nachází.
Poznámka
Chcete-li vytvořit nestatickou třídu, která umožňuje vytvořit pouze jednu instanci sebe sama, viz téma implementace typu Singleton v jazyce C#.
Následující seznam poskytuje hlavní funkce statické třídy:
Obsahuje pouze statické členy.
Nelze vytvořit instanci.
Je zapečetěný.
Nemůže obsahovat konstruktory instancí.
Vytvoření statické třídy je proto v podstatě stejné jako vytvoření třídy, která obsahuje pouze statické členy a soukromý konstruktor. Privátní konstruktor zabraňuje vytvoření instance třídy. Výhodou použití statické třídy je, že kompilátor může zkontrolovat, zda nejsou omylem přidány žádné členy instance. Kompilátor zajistí, ž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 s výjimkou Object . Statické třídy nemůžou obsahovat konstruktor instance. Mohou však obsahovat statický konstruktor. Nestatické třídy by měly také definovat statický konstruktor, pokud třída obsahuje statické členy, které vyžadují netriviá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 z Celsia na Fahrenheita a z Fahrenheita na Celsia:
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.
*/
Statické členy
Nestatická třída může obsahovat statické metody, pole, vlastnosti nebo události. Statický člen je volat na třídu, i když nebyla vytvořena žádná instance třídy. K statickému členu se vždy používá název třídy, nikoli název instance. Existuje pouze jedna kopie statického člena bez ohledu na to, kolik instancí třídy je vytvořeno. Statické metody a vlastnosti nemají přístup k nestatickým polím a událostem ve svých nadřazených typech a nemohou přistupovat k proměnné instance žádného objektu, pokud není explicitně předána parametrem metody.
Je obvyklejší deklarovat nestatickou třídu s některými statickými členy, než deklarovat celou třídu jako statickou. Dvě společná použití statických polí jsou uchovávají počet objektů, které byly vytvořeny instance, nebo ukládají hodnotu, která musí být sdílena mezi všemi instancemi.
Statické metody mohou být přetíženy, ale nejsou přepsány, protože patří do třídy, a nikoli do žádné instance třídy.
I když pole nemůže být deklarováno jako static const , pole const je v podstatě statické v jeho chování. Patří do typu, nikoli do instancí typu. Proto const lze k polím přistupovat pomocí stejného ClassName.MemberName zápisu, který je použit pro statická pole. Není požadována žádná instance objektu.
Jazyk C# nepodporuje statické lokální proměnné (tj. proměnné, které jsou deklarovány v oboru metody).
Statické členy třídy deklarujete pomocí static klíčového slova 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
{
get
{
return 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 otevřením statického člena a před statickým konstruktorem, pokud je volána. Chcete-li získat přístup ke členu statické třídy, použijte název třídy namísto názvu proměnné pro určení umístění člena, jak je znázorněno v následujícím příkladu:
Automobile.Drive();
int i = Automobile.NumberOfWheels;
Pokud vaše třída obsahuje statická pole, poskytněte statický konstruktor, který je inicializuje při načtení třídy.
Volání statické metody generuje instrukci volání v jazyce MSIL (Microsoft Intermediate Language), zatímco volání metody instance vygeneruje callvirt instrukci, která také kontroluje odkazy na objekty s hodnotou null. Ale ve většině případů není rozdíl mezi výkonem mezi těmito dvěma důležitý.
Specifikace jazyka C#
Další informace naleznete v tématu statické třídy a statické a instance členů ve specifikaci jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.