Klasy statyczne i statyczni członkowie klas (Przewodnik programowania w języku C#)
Klasa statyczna jest zasadniczo taka sama jak klasa niestatyczna, ale istnieje jedna różnica: nie można utworzyć wystąpienia klasy statycznej. Innymi słowy, nie można użyć nowego operatora do utworzenia zmiennej typu klasy. Ponieważ nie ma zmiennej wystąpienia, uzyskujesz dostęp do składowych klasy statycznej przy użyciu samej nazwy klasy. Jeśli na przykład masz klasę statyczną o nazwie UtilityClass
, która ma publiczną metodę statyczną o nazwie MethodA
, wywołaj metodę, jak pokazano w poniższym przykładzie:
UtilityClass.MethodA();
Klasę statyczną można użyć jako wygodnego kontenera dla zestawów metod, które działają tylko na parametrach wejściowych i nie trzeba pobierać ani ustawiać żadnych pól wystąpienia wewnętrznego. Na przykład w bibliotece klas platformy .NET statyczna System.Math klasa zawiera metody, które wykonują operacje matematyczne, bez konieczności przechowywania ani pobierania danych unikatowych dla określonego Math wystąpienia klasy. Oznacza to, że należy zastosować składowe klasy, określając nazwę klasy i nazwę metody, jak pokazano w poniższym przykładzie.
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
Podobnie jak w przypadku wszystkich typów klas środowisko uruchomieniowe platformy .NET ładuje informacje o typie dla klasy statycznej, gdy program odwołujący się do klasy jest ładowany. Program nie może określić dokładnie, kiedy klasa jest ładowana. Jednak gwarantowane jest załadowanie i zainicjowanie pól oraz wywołanie jego konstruktora statycznego przed odwołaniem do klasy po raz pierwszy w programie. Konstruktor statyczny jest wywoływany tylko raz, a klasa statyczna pozostaje w pamięci przez okres istnienia domeny aplikacji, w której znajduje się program.
Uwaga
Aby utworzyć klasę niestacyjną, która umożliwia utworzenie tylko jednego wystąpienia samego siebie, zobacz Implementowanie pojedynczego wystąpienia w języku C#.
Poniższa lista zawiera główne funkcje klasy statycznej:
Zawiera tylko statyczne elementy członkowskie.
Nie można utworzyć wystąpienia wystąpienia.
Jest zapieczętowany.
Nie można zawierać konstruktorów wystąpień.
Dlatego tworzenie klasy statycznej jest w zasadzie takie samo jak tworzenie klasy, która zawiera tylko statyczne elementy członkowskie i konstruktor prywatny. Konstruktor prywatny uniemożliwia utworzenie wystąpienia klasy. Zaletą używania klasy statycznej jest to, że kompilator może sprawdzić, czy nie zostały przypadkowo dodane żadne elementy członkowskie wystąpienia. Kompilator gwarantuje, że nie można utworzyć wystąpień tej klasy.
Klasy statyczne są zapieczętowane i dlatego nie można ich dziedziczyć. Nie mogą dziedziczyć z żadnej klasy ani interfejsu z wyjątkiem Object. Klasy statyczne nie mogą zawierać konstruktora wystąpienia. Mogą jednak zawierać konstruktor statyczny. Klasy niestatyczne powinny również definiować konstruktor statyczny, jeśli klasa zawiera statyczne elementy członkowskie, które wymagają inicjalizacji nietypowej. Aby uzyskać więcej informacji, zobacz Konstruktory statyczne.
Przykład
Oto przykład klasy statycznej zawierającej dwie metody konwertujące temperaturę z Stopni Celsjusza na Fahrenheit i Fahrenheit na Stopnie Celsjusza:
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.
*/
Statyczne elementy członkowskie
Klasa niestatyczna może zawierać metody statyczne, pola, właściwości lub zdarzenia. Statyczny element członkowski można wywołać w klasie nawet wtedy, gdy nie istnieje żadne wystąpienie klasy. Statyczny element członkowski jest zawsze uzyskiwany przez nazwę klasy, a nie nazwę wystąpienia. Istnieje tylko jedna kopia statycznego elementu członkowskiego, niezależnie od liczby wystąpień klasy. Metody statyczne i właściwości nie mogą uzyskać dostępu do pól i zdarzeń nie statycznych w ich typie zawierającym i nie mogą uzyskać dostępu do zmiennej wystąpienia dowolnego obiektu, chyba że jawnie przekazano go w parametrze metody.
Bardziej typowe jest deklarowanie klasy niestatycznej z niektórymi statycznymi elementami członkowskimi niż deklarowanie całej klasy jako statycznej. Dwa typowe zastosowania pól statycznych to zachowanie liczby wystąpień obiektów lub przechowywanie wartości, która musi być współdzielona między wszystkimi wystąpieniami.
Metody statyczne mogą być przeciążone, ale nie przesłaniane, ponieważ należą do klasy, a nie do żadnego wystąpienia klasy.
Chociaż nie można zadeklarować pola jako static const
, pole const jest zasadniczo statyczne w jego zachowaniu. Należy do typu, a nie do wystąpień typu. const
W związku z tym dostęp do pól można uzyskać przy użyciu tej samej ClassName.MemberName
notacji używanej dla pól statycznych. Nie jest wymagane żadne wystąpienie obiektu.
Język C# nie obsługuje statycznych zmiennych lokalnych (czyli zmiennych zadeklarowanych w zakresie metody).
Składowe klas statycznych są deklarowane przy użyciu static
słowa kluczowego przed typem zwrotnym elementu członkowskiego, jak pokazano w poniższym przykładzie:
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...
}
Statyczne elementy członkowskie są inicjowane przed uzyskaniem dostępu do statycznego elementu członkowskiego po raz pierwszy i przed wywołaniem konstruktora statycznego. Aby uzyskać dostęp do statycznej składowej klasy, użyj nazwy klasy zamiast nazwy zmiennej, aby określić lokalizację składowej, jak pokazano w poniższym przykładzie:
Automobile.Drive();
int i = Automobile.NumberOfWheels;
Jeśli klasa zawiera pola statyczne, podaj konstruktor statyczny, który inicjuje je podczas ładowania klasy.
Wywołanie metody statycznej generuje instrukcję wywołania w typowym języku pośrednim (CIL), podczas gdy wywołanie metody wystąpienia generuje callvirt
instrukcję, która sprawdza również odwołania do obiektu o wartości null. Jednak w większości przypadków różnica wydajności między nimi nie jest znacząca.
Specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz Statyczne klasy, składowe statyczne i wystąpienia oraz konstruktory statyczne w specyfikacji języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.