← Назад к вопросам

В чём разница между const, readonly и static?

1.2 Junior🔥 161 комментариев
#Основы C# и .NET

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между const, readonly и static в C#

В C# модификаторы const, readonly и static используются для управления поведением членов класса, но они решают разные задачи и имеют различные характеристики. Понимание их отличий критически важно для написания корректного и эффективного кода.

1. Const (Константы)

const используется для объявления компиляторных констант. Эти константы должны быть инициализированы при объявлении, и их значение не может быть изменено ни при каких обстоятельствах.

Ключевые особенности:

  • Значение должно быть известно на этапе компиляции
  • Может использоваться только с типами-значениями и строками
  • Неявно является static (доступ через имя класса)
  • Хранится в метаданных сборки
public class MathConstants
{
    public const double PI = 3.14159;
    public const string AppName = "MyApplication";
    // public const DateTime StartDate = DateTime.Now; // ОШИБКА! Значение должно быть известно при компиляции
}

// Использование
double circumference = 2 * MathConstants.PI * radius;

2. Readonly (Только для чтения)

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

Ключевые особенности:

  • Инициализируется при объявлении или в конструкторе
  • Значение может вычисляться во время выполнения
  • Может использоваться с любыми типами данных
  • Может быть как статическим, так и экземплярным
public class Configuration
{
    // Инициализация при объявлении
    public readonly string ConnectionString = "default_connection";
    
    // Инициализация в конструкторе
    public readonly DateTime StartTime;
    
    // Статическое readonly поле
    public static readonly DateTime AppStartTime = DateTime.Now;
    
    public Configuration(string customConnection)
    {
        // Можно изменить в конструкторе
        ConnectionString = customConnection;
        StartTime = DateTime.Now;
    }
    
    public void UpdateConnection()
    {
        // ConnectionString = "new_value"; // ОШИБКА! Нельзя изменить вне конструктора
    }
}

3. Static (Статические члены)

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

Ключевые особенности:

  • Принадлежит классу, а не экземпляру
  • Существует в единственном экземпляре
  • Можно комбинировать с readonly для статических констант времени выполнения
  • Не может использоваться с const (поскольку const и так неявно статический)
public class Logger
{
    // Статическое поле
    private static int logCounter = 0;
    
    // Статическое свойство
    public static string LogDirectory { get; set; }
    
    // Статическое readonly поле
    public static readonly DateTime InitializationTime = DateTime.Now;
    
    // Статический метод
    public static void Log(string message)
    {
        logCounter++;
        Console.WriteLine($"[{logCounter}] {message}");
    }
}

// Использование
Logger.Log("Application started");

Сравнительная таблица

Характеристикаconstreadonlystatic
Время инициализацииПри компиляцииПри объявлении или в конструктореПри первом обращении или запуске программы
ИзменяемостьНикогда не изменяетсяТолько в конструктореМожет изменяться (если не readonly)
ПринадлежностьКлассу (неявно static)Экземпляру или классуКлассу
Типы данныхТолько примитивные типы и строкиЛюбые типыЛюбые типы
ВычисленияТолько константные выраженияМогут быть вычисления во время выполненияМогут быть вычисления во время выполнения
ПамятьХранится в метаданныхХранится в куче (экземпляр) или статической памяти (статический)Статическая память

Практические рекомендации

  1. Используйте const для значений, которые точно известны при компиляции и никогда не изменятся (математические константы, строки конфигурации).

  2. Используйте readonly когда:

    • Значение вычисляется во время выполнения
    • Нужна неизменяемость после инициализации
    • Используются сложные типы данных
  3. Используйте static readonly для констант времени выполнения, которые должны быть общими для всех экземпляров:

    public static readonly DateTime StartupTime = DateTime.Now;
    
  4. Комбинируйте static и readonly для создания потокобезопасных неизменяемых статических данных.

  5. Избегайте изменяемых публичных статических полей — они могут приводить к проблемам с потокобезопасностью и сложностям в тестировании.

Выбор между этими модификаторами зависит от конкретных требований: нужна ли константа времени компиляции или выполнения, должна ли она быть связана с экземпляром или классом, может ли значение изменяться после инициализации. Правильное использование этих модификаторов делает код более безопасным, понятным и эффективным.