Поделиться через


Статические классы и члены статических классов (руководство по программированию на C#)

Статический класс аналогичен не статическому классу, за исключением одной разницы: статический класс не может быть инстанцирован. Другими словами, нельзя использовать новый оператор для создания переменной типа класса. Так как переменная экземпляра отсутствует, вы обращаетесь к членам статического класса с помощью самого имени класса. Например, если у вас есть статический класс, который называется UtilityClass с открытым статическим методом с именем MethodA, вызывается метод, как показано в следующем примере:

UtilityClass.MethodA();

Статический класс можно использовать в качестве удобного контейнера для наборов методов, которые просто работают с входными параметрами и не должны получать или задавать поля внутреннего экземпляра. Например, в библиотеке классов .NET статический System.Math класс содержит методы, выполняющие математические операции без необходимости хранить или извлекать данные, уникальные для определенного экземпляра класса Math. То есть примените элементы класса, указав имя класса и имя метода, как показано в следующем примере.

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 загружает сведения о типе статического класса при загрузке программы, ссылающейся на класс. Программа не может точно указать, когда загружается класс. Однако он гарантированно загружает и инициализирует поля и вызывается статическим конструктором до того, как класс ссылается впервые в вашей программе. Статический конструктор вызывается только один раз, и статический класс остается в памяти в течение всего времени существования домена приложения, в котором находится ваша программа.

Примечание.

Чтобы создать нестатический класс, где создаётся только один экземпляр, см. реализацию Singleton в C#.

В следующем списке представлены основные функции статического класса:

  • Содержит только статические элементы.

  • Невозможно создать экземпляр.

  • Запечатан.

  • Не удается включить конструкторы экземпляров .

Поэтому создание статического класса в основном совпадает с созданием класса, содержащего только статические элементы и закрытый конструктор. Приватный конструктор предотвращает создание экземпляра класса. Преимущество использования статического класса заключается в том, что компилятор может проверить, что элементы экземпляра не добавляются случайно. Компилятор гарантирует, что экземпляры этого класса не могут быть созданы.

Статические классы запечатаны и поэтому не могут быть унаследованы. Они не могут наследоваться от любого класса или интерфейса, кроме Object. Статические классы не могут содержать конструктор экземпляра. Однако они могут содержать статический конструктор. Нестатические классы также должны определять статический конструктор, если класс содержит статические элементы, требующие нетривиальной инициализации. Дополнительные сведения см. в статические конструкторы.

Пример

Ниже приведен пример статического класса, который содержит два метода, которые преобразуют температуру из Цельсия в Fahrenheit и из Fahrenheit в Цельсию:

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

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

Статические члены

Нестатический класс может содержать статические методы, поля, свойства или события. Статический член может вызываться через класс, даже если экземпляр класса не создан. Статический элемент всегда обращается к имени класса, а не имени экземпляра. Существует только одна копия статического члена независимо от того, сколько экземпляров класса создается. Статические методы и свойства не могут получить доступ к нестатическому полям и событиям в их содержательном типе, и они не могут получить доступ к переменной экземпляра любого объекта, если он не передается явным образом в параметре метода.

Обычно объявлять нестатический класс с некоторыми статическими элементами, чем объявлять весь класс как статический. Два распространенных использования статических полей — хранить количество объектов, которые были созданы, или хранить значение, общее для всех экземпляров.

Статические методы могут быть перегружены, но не переопределены, так как они принадлежат к классу, а не к любому экземпляру класса.

Хотя поле не может быть объявлено как static const, поле констант по сути является статическим в его поведении. Он принадлежит типу, а не экземплярам типа. Таким образом, const поля можно получить с помощью той же ClassName.MemberName нотации, используемой для статических полей. Экземпляр объекта не требуется.

C# не поддерживает статические локальные переменные (то есть переменные, объявленные в области метода).

Вы объявляете элементы статического класса с помощью ключевого слова static перед типом возвращаемого элемента, как показано в следующем примере:

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

Статические члены инициализированы перед первым доступом к статическому элементу и до вызова статического конструктора. Чтобы получить доступ к элементу статического класса, используйте имя класса вместо имени переменной, чтобы указать расположение элемента, как показано в следующем примере:

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

Если класс содержит статические поля, укажите статический конструктор, который инициализирует их при загрузке класса.

Вызов статического метода создает инструкцию вызова в общем промежуточном языке (CIL), а вызов метода экземпляра создает инструкцию callvirt, которая также проверяет наличие ссылок на объекты NULL. Однако большую часть времени разница между этими двумя производительностью не является значительной.

Спецификация языка C#

Дополнительные сведения см. в статических классах, статических и экземплярных элементах и статических конструкторах в спецификации языка C# . Спецификация языка является авторитетным источником синтаксиса и использования C#.

См. также