Статические классы и члены статических классов (Руководство по программированию в C#)Static Classes and Static Class Members (C# Programming Guide)

Статический класс в основном такой же, как и нестатический класс, но имеется одно отличие: нельзя создавать экземпляры статического класса.A static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated. Другими словами, нельзя использовать оператор new для создания переменной типа класса.In other words, you cannot use the new operator to create a variable of the class type. Поскольку нет переменной экземпляра, доступ к членам статического класса осуществляется с использованием самого имени класса.Because there is no instance variable, you access the members of a static class by using the class name itself. Например, если есть статический класс, называемый UtilityClass, имеющий открытый статический метод с именем MethodA, вызов метода выполняется, как показано в следующем примере:For example, if you have a static class that is named UtilityClass that has a public static method named MethodA, you call the method as shown in the following example:

UtilityClass.MethodA();  

Статический класс может использоваться как обычный контейнер для наборов методов, работающих на входных параметрах, и не должен возвращать или устанавливать каких-либо внутренних полей экземпляра.A static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields. Например, в библиотеке классов .NET Framework статический класс System.Math содержит методы, выполняющие математические операции, без требования сохранять или извлекать данные, уникальные для конкретного экземпляра класса Math.For example, in the .NET Framework Class Library, the static System.Math class contains methods that perform mathematical operations, without any requirement to store or retrieve data that is unique to a particular instance of the Math class. Это значит, что члены класса применяются путем задания имени класса и имени метода, как показано в следующем примере.That is, you apply the members of the class by specifying the class name and the method name, as shown in the following example.

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 Framework CLR, когда загружается программа, которая ссылается на класс.As is the case with all class types, the type information for a static class is loaded by the .NET Framework common language runtime (CLR) when the program that references the class is loaded. Программа не может точно указать, когда загружается класс.The program cannot specify exactly when the class is loaded. Однако гарантируется загрузка этого класса, инициализация его полей и вызов статического конструктора перед первым обращением к классу в программе.However, it is guaranteed to be loaded and to have its fields initialized and its static constructor called before the class is referenced for the first time in your program. Статический конструктор вызывается только один раз, и статический класс остается в памяти на время существования домена приложения, в котором находится программа.A static constructor is only called one time, and a static class remains in memory for the lifetime of the application domain in which your program resides.

Примечание

Создание нестатического класса, который допускает создание только одного экземпляра самого себя, см. в документе Реализация Singleton в C#.To create a non-static class that allows only one instance of itself to be created, see Implementing Singleton in C#.

Ниже приведены основные возможности статического класса.The following list provides the main features of a static class:

  • Содержит только статические члены.Contains only static members.

  • Создавать его экземпляры нельзя.Cannot be instantiated.

  • Является запечатанным.Is sealed.

  • Не может содержать конструкторы экземпляров.Cannot contain Instance Constructors.

По сути, создание статического класса аналогично созданию класса, содержащего только статические члены и закрытый конструктор.Creating a static class is therefore basically the same as creating a class that contains only static members and a private constructor. Закрытый конструктор не допускает создания экземпляров класса.A private constructor prevents the class from being instantiated. Преимущество применения статических классов заключается в том, что компилятор может проверить отсутствие случайно добавленных членов экземпляров.The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. Таким образом, компилятор гарантирует невозможность создания экземпляров таких классов.The compiler will guarantee that instances of this class cannot be created.

Статические классы запечатаны, поэтому их нельзя наследовать.Static classes are sealed and therefore cannot be inherited. Они не могут наследовать ни от каких классов, кроме Object.They cannot inherit from any class except Object. Статические классы не могут содержать конструктор экземпляров, но могут содержать статический конструктор.Static classes cannot contain an instance constructor; however, they can contain a static constructor. Нестатические классы также должен определять статический конструктор, если класс содержит статические члены, для которых нужна нетривиальная инициализация.Non-static classes should also define a static constructor if the class contains static members that require non-trivial initialization. Дополнительные сведения см. в разделе Статические конструкторы.For more information, see Static Constructors.

ПримерExample

Ниже приведен пример статического класса, содержащего два метода, преобразующих температуру по Цельсию в температуру по Фаренгейту и наоборот.Here is an example of a static class that contains two methods that convert temperature from Celsius to Fahrenheit and from Fahrenheit to 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());
                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.
 */

Статический членыStatic Members

Нестатический класс может содержать статические методы, поля, свойства или события.A non-static class can contain static methods, fields, properties, or events. Статический член вызывается для класса даже в том случае, если не создан экземпляр класса.The static member is callable on a class even when no instance of the class has been created. Доступ к статическому члены всегда выполняется по имени класса, а не экземпляра.The static member is always accessed by the class name, not the instance name. Существует только одна копия статического члена, независимо от того, сколько создано экземпляров класса.Only one copy of a static member exists, regardless of how many instances of the class are created. Статические методы и свойства не могут обращаться к нестатическим полям и событиям в их содержащем типе, и они не могут обращаться к переменной экземпляра объекта, если он не передается явно в параметре метода.Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.

Более привычно объявление нестатического класса с несколькими статическими членами, чем объявление всего класса как статического.It is more typical to declare a non-static class with some static members, than to declare an entire class as static. Статические поля обычно используются для следующих двух целей: хранение счетчика числа созданных объектов или хранение значения, которое должно совместно использоваться всеми экземплярами.Two common uses of static fields are to keep a count of the number of objects that have been instantiated, or to store a value that must be shared among all instances.

Статические методы могут быть перегружены, но не переопределены, поскольку они относятся к классу, а не к экземпляру класса.Static methods can be overloaded but not overridden, because they belong to the class, and not to any instance of the class.

Несмотря на то, что поле не может быть объявлено как static const, поле const по своему поведению является статическим.Although a field cannot be declared as static const, a const field is essentially static in its behavior. Он относится к типу, а не к экземплярам типа.It belongs to the type, not to instances of the type. Поэтому к полям const можно обращаться с использованием той же нотации ClassName.MemberName, что и для статических полей.Therefore, const fields can be accessed by using the same ClassName.MemberName notation that is used for static fields. Экземпляр объекта не требуется.No object instance is required.

C# не поддерживает статические локальные переменные (переменные, объявленные в области действия метода).C# does not support static local variables (variables that are declared in method scope).

Для объявления статических методов класса используется ключевое слово static перед возвращаемым типом члена, как показано в следующем примере:You declare static class members by using the static keyword before the return type of the member, as shown in the following example:

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

Статические члены инициализируются перед первым доступом к статическому члену и перед вызовом статического конструктора, если таковой имеется.Static members are initialized before the static member is accessed for the first time and before the static constructor, if there is one, is called. Для доступа к члену статического класса следует использовать имя класса, а не имя переменной, указывая расположение члена, как показано в следующем примере:To access a static class member, use the name of the class instead of a variable name to specify the location of the member, as shown in the following example:

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

Если класс содержит статические поля, должен быть указан статический конструктор, который инициализирует эти поля при загрузке класса.If your class contains static fields, provide a static constructor that initializes them when the class is loaded.

Вызов статического метода генерирует инструкцию вызова в промежуточном языке Microsoft (MSIL), в то время как вызов метода экземпляра генерирует инструкцию callvirt, которая также проверяет наличие ссылок на пустые объекты.A call to a static method generates a call instruction in Microsoft intermediate language (MSIL), whereas a call to an instance method generates a callvirt instruction, which also checks for a null object references. Однако в большинстве случаев разница в производительности двух видов вызовов несущественна.However, most of the time the performance difference between the two is not significant.

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

Дополнительные сведения см. в разделах Статические классы и Члены экземпляра и статические члены в документации Предварительная спецификация C# 6.0.For more information, see Static classes and Static and instance members in the C# Language Specification. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.The language specification is the definitive source for C# syntax and usage.

См. такжеSee also