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

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

1.0 Junior🔥 142 комментариев
#C# и ООП

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

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

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

Различие между const и readonly в C#

Основное различие между const и readonly в C# заключается в времени инициализации, типах данных и области использования, что делает их применимыми в разных сценариях разработки на Unity или любом другом C#-проекте.

Ключевые отличия

Аспектconstreadonly
Время инициализацииКомпиляция (compile-time)Выполнение (runtime)
Типы данныхТолько примитивы и строкиЛюбые, включая ссылочные типы
Область видимостиТолько статические членыПоля экземпляра или статические
Вычисление значенийЗначение должно быть известно на этапе компиляцииМожет вычисляться в конструкторе

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

const представляет собой статические константы, значение которых должно быть известно на этапе компиляции. Они встраиваются непосредственно в код, что может повысить производительность, но ограничивает гибкость.

public class GameSettings {
    public const float MaxHealth = 100f; // Должно быть вычисляемо при компиляции
    public const string GameVersion = "1.0.0";
    
    // НЕЛЬЗЯ использовать с объектами:
    // const Vector3 spawnPoint = new Vector3(0, 0, 0); // Ошибка компиляции!
}

Особенности const:

  • Статические по своей природе (обращение: ClassName.ConstName)
  • Не могут быть изменены после компиляции
  • Ограничены примитивными типами, перечислениями и строками
  • В Unity часто используются для математических констант, тегов, путей

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

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

public class Player {
    // readonly поле может быть инициализировано при объявлении или в конструкторе
    private readonly float _maxSpeed;
    private readonly Rigidbody _rigidbody;
    private readonly DateTime _createdDate;
    
    public Player(float speed, Rigidbody rb) {
        // Инициализация в конструкторе
        _maxSpeed = speed; // Можно установить разное значение для разных экземпляров
        _rigidbody = rb;
        _createdDate = DateTime.Now; // Значение вычисляется во время выполнения
    }
    
    // Readonly можно использовать и для статических полей
    public static readonly Vector3 DefaultSpawn = new Vector3(0, 1, 0);
}

Особенности readonly:

  • Могут быть как статическими, так и нестатическими
  • Допускают использование любых типов данных
  • Инициализируются в конструкторе или при объявлении
  • В Unity полезны для компонентов, настроек экземпляров, зависимостей

Практическое применение в Unity

public class Weapon : MonoBehaviour {
    // Const для значений, известных на этапе разработки
    public const float BaseDamageMultiplier = 1.5f;
    public const string WeaponTag = "PlayerWeapon";
    
    // Readonly для ссылок на компоненты и настройки экземпляра
    private readonly float _uniqueDamageModifier;
    private Animator _animator;
    
    void Awake() {
        _animator = GetComponent<Animator>();
        // Readonly поля НЕ могут быть изменены здесь (только в конструкторе)
    }
    
    // Readonly свойства (C# 8.0+)
    public float TotalDamage { get; } // Может быть установлено только в конструкторе
}

Сравнение в контексте производительности

// Пример различия в использовании
public class PerformanceTest {
    // Const заменяется значением на этапе компиляции
    public const int ConstValue = 100;
    
    // Readonly доступ через ссылку во время выполнения
    public static readonly int ReadonlyValue = 200;
    
    void Test() {
        int a = ConstValue * 2; // В бинарнике: int a = 100 * 2;
        int b = ReadonlyValue * 2; // В бинарнике: обращение к полю
    }
}

Рекомендации по выбору

Используйте const, когда:

  • Значение точно известно на этапе компиляции
  • Работаете с примитивными типами или строками
  • Нужна максимальная производительность (избегаете вызовов в памяти)
  • Значение универсально для всех экземпляров

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

  • Значение зависит от runtime-логики
  • Работаете со ссылочными типами (компоненты Unity, объекты)
  • Нужна инициализация в конструкторе
  • Значение может различаться между экземплярами

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