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


static (справочник по C#)

На этой странице рассматривается ключевое static слово модификатора. Ключевое static слово также является частью директивы using static .

static Используйте модификатор для объявления статического элемента, который принадлежит самому типу, а не конкретному объекту. Модификатор static можно использовать для объявления классов static. В классах, интерфейсах и структурах можно добавить static модификатор в поля, методы, свойства, операторы, события и конструкторы. static Модификатор нельзя использовать с индексаторами или финализаторами. Дополнительные сведения см. в статье Статические классы и члены статических классов.

Модификатор static можно добавить в локальную функцию. Статическая локальная функция не может захватывать локальные переменные или состояние экземпляра.

class Calc1
{
    public void CalculateSum()
    {
        int a = 3;
        int b = 7;

        // Static local function - cannot access 'a' or 'b' directly
        static int Add(int x, int y)
        {
            return x + y;
        }

        int result = Add(a, b); 
        Console.WriteLine($"Sum: {result}");
    }
}
  /*
 Output:
 Sum: 10
 */

Модификатор можно добавить в staticлямбда-выражение или анонимный метод. Статический лямбда-метод или анонимный метод не может записывать локальные переменные или состояние экземпляра.

class Calc2
{
    static void Main()
    {
        Func<int, int, int> add = static (a, b) => a + b;

        int result = add(5, 10);
        Console.WriteLine($"Sum: {result}");
    }
}
/*
Output:
Sum: 15
*/

Пример — статический класс

Следующий класс объявляется как static и содержит только static методы:

static class CompanyEmployee
{
    public static void DoSomething() { /*...*/ }
    public static void DoSomethingElse() { /*...*/  }
}

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

public class MyBaseC
{
    public struct MyStruct
    {
        public static int x = 100;
    }
}

Чтобы ссылаться на static член x, используйте полное имя, MyBaseC.MyStruct.xесли член не доступен из той же области:

Console.WriteLine(MyBaseC.MyStruct.x);

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

Невозможно использовать this для ссылки на static методы или методы доступа к свойствам.

Если ключевое static слово применяется к классу, все члены класса должны быть static.

У классов, интерфейсов и static классов могут быть static конструкторы. Конструктор static вызывается в какой-то момент после запуска программы и перед созданием экземпляра класса.

Замечание

Ключевое static слово имеет более ограниченное использование, чем в C++. Сведения о сравнении с ключевым словом C++ см. в разделе "Классы хранилища" (C++).

Чтобы продемонстрировать static участников, рассмотрите класс, представляющий сотрудника компании. Предположим, что класс содержит метод для подсчета сотрудников и поля для хранения количества сотрудников. Метод и поле не принадлежат никакому конкретному экземпляру сотрудника. Вместо этого они принадлежат к классу сотрудников в целом. Они должны быть объявлены static как члены класса.

Пример : статическое поле и метод

В этом примере считывается имя и идентификатор нового сотрудника, счетчик сотрудников увеличивается на единицу и отображается информация о новом сотруднике и общее число сотрудников. Эта программа считывает текущее число сотрудников с клавиатуры.

public class Employee4
{
    public string id;
    public string name;

    public Employee4()
    {
    }

    public Employee4(string name, string id)
    {
        this.name = name;
        this.id = id;
    }

    public static int employeeCounter;

    public static int AddEmployee()
    {
        return ++employeeCounter;
    }
}

class MainClass : Employee4
{
    static void Main()
    {
        Console.Write("Enter the employee's name: ");
        string name = Console.ReadLine();
        Console.Write("Enter the employee's ID: ");
        string id = Console.ReadLine();

        // Create and configure the employee object.
        Employee4 e = new Employee4(name, id);
        Console.Write("Enter the current number of employees: ");
        string n = Console.ReadLine();
        Employee4.employeeCounter = Int32.Parse(n);
        Employee4.AddEmployee();

        // Display the new information.
        Console.WriteLine($"Name: {e.name}");
        Console.WriteLine($"ID:   {e.id}");
        Console.WriteLine($"New Number of Employees: {Employee4.employeeCounter}");
    }
}
/*
Input:
Matthias Berndt
AF643G
15
 *
Sample Output:
Enter the employee's name: Matthias Berndt
Enter the employee's ID: AF643G
Enter the current number of employees: 15
Name: Matthias Berndt
ID:   AF643G
New Number of Employees: 16
*/

Пример — статическая инициализация

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

class Test
{
    static int x = y;
    static int y = 5;

    static void Main()
    {
        Console.WriteLine(Test.x);
        Console.WriteLine(Test.y);

        Test.x = 99;
        Console.WriteLine(Test.x);
    }
}
/*
Output:
    0
    5
    99
*/

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

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

См. также