Ответ
Константа (const) — это идентификатор, значение которого известно на этапе компиляции и не может быть изменено в течение всего времени жизни приложения.
Характеристики и синтаксис:
public const int MaxRetryCount = 3;
public const string ProductName = "MyApp";
public const double Pi = 3.14159;
Ключевые особенности const:
- Компиляция: Значение подставляется прямо в IL-код везде, где используется константа. Изменение константы требует перекомпиляции всех зависимых сборок.
- Типы данных: Могут быть только типами-значениями (
int,double,bool,enum),stringилиnull. - Область видимости: Неявно являются
static. Обращение:ClassName.ConstantName. - Инициализация: Должны быть проинициализированы при объявлении.
Когда использовать const?
Для истинно неизменяемых, фундаментальных значений, известных на этапе компиляции:
- Математические константы (
Math.PI— на самом делеstatic readonly, но концептуально). - Коды ошибок, магические числа.
- Фиксированные строки-идентификаторы.
Альтернатива: readonly поле
Используйте readonly, когда значение неизменно, но вычисляется в runtime (например, при создании объекта) или имеет недопустимый для const тип.
public class Config
{
// Значение можно задать в конструкторе или инициализаторе
public readonly DateTime StartupTime = DateTime.UtcNow;
public readonly List<string> SupportedLanguages;
public Config()
{
SupportedLanguages = LoadLanguages(); // runtime-инициализация
}
}
Сравнение const vs readonly: |
Критерий | const |
readonly |
|---|---|---|---|
| Время вычисления | Компиляция | Выполнение (runtime) | |
| Типы данных | Примитивы, string, enum |
Любые | |
Модификатор static |
Неявно статическая | Может быть как статическим, так и экземплярным | |
| Обновление значения | Требует перекомпиляции всех клиентов | Достаточно перекомпиляции только сборки, где объявлено поле |
Ответ 18+ 🔞
А, константы, блядь! Ну это ж классика, хуле. Сидишь такой, пишешь код, и думаешь: "А не впендюрить ли мне сюда волшебное число 3?" А потом через полгода приходит коллега и спрашивает: "А это что за цифра 3, на которую всё завязано?" И ты такой: "Ну это... типа три попытки..." А он: "А почему не четыре?" И ты понимаешь, что ебал в рот этот магический номер, надо было константу делать.
Вот смотри, const — это как татуировка на жопе. На этапе компиляции её уже набили, и переписать "Люблю маму" на "Люблю папу" без боли и перекомпиляции всего, что на эту жопу смотрит, — нихуя не выйдет.
public const int MaxRetryCount = 3; // Всё, приехали. Тройка навеки.
public const string ProductName = "MyApp"; // Название, и ни шага в сторону.
public const double Pi = 3.14159; // Даже пи у нас своё, блядь, округлённое.
Чем эта штука характерна, а?
- Подстановка намертво: Компилятор берёт значение и вставляет его прямо в скомпилированный код, как засохшую жвачку под стол. Меняешь константу — всё, что от неё зависело, надо пересобирать заново, иначе будут смотреть на старое значение. Полный пиздец и разрушение доверия.
- Типы скудные: Только примитивы (
int,bool),stringилиenum. ХочешьDateTimeилиListсделать константой? Иди на хуй, так не работает. - Статика по умолчанию: Они неявно
static. Обращаешься к ней какClassName.ConstantName, а не через экземпляр. Логично же, раз значение одно на всех. - Инициализация сразу: Объявил — тут же, блядь, присвой значение. Отложить на потом нельзя, runtime тебе не помощник.
Так когда её, блять, использовать-то? Да когда у тебя значение реально, нахуй, неизменное и известно прямо сейчас, когда ты код пишешь. Типа:
- Математические константы (хотя
Math.PI— этоreadonly, но суть ты понял). - Коды ошибок, которые в API прописаны.
- Разные "магические числа", которые разбросаны по коду, чтобы их в одном месте собрать и назвать человечьим языком.
А если значение в runtime появляется?
Тогда твой выход — readonly поле, друг мой. Это как временная татуха, которую можно нарисовать при создании объекта и потом уже не стирать.
public class Config
{
// Время старта программы. На момент компиляции кто ж его знает?
public readonly DateTime StartupTime = DateTime.UtcNow;
// Список языков. Его из файла или базы подтягиваем, а не в коде хардкодим.
public readonly List<string> SupportedLanguages;
public Config()
{
SupportedLanguages = LoadLanguages(); // Вот тут, во время выполнения, инициализируем.
}
}
Короче, краткая сводка, чтобы не ебать мозг:
| Критерий | const |
readonly |
|---|---|---|
| Когда значение известно | При компиляции | При выполнении (runtime) |
| Какие типы прокатят | Примитивы, строки, енамы | Любые, хоть HttpClient |
| Статика | Да, всегда | Может быть и статическим, и нет |
| Как обновить | Пересобрать всё, что её использует | Пересобрать только сборку, где поле объявлено |
Вывод простой: если значение фундаментальное и менять его не планируется никогда — const. Если значение неизменное после создания, но вычисляется при работе программы или тип сложный — readonly. Не путай, а то будет тебе хиросима.