0Pricing
C# Academy · Урок

Константы и поля readonly

Различайте const и static readonly.

«Константы и поля readonly» — бесплатный урок C# Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Два способа сделать значения неизменяемыми

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

using System;

class Config
{
    public const double Pi = 3.14159;
    public static readonly DateTime StartedAt = DateTime.Now;
}

class Program
{
    static void Main()
    {
        Console.WriteLine("Pi = " + Config.Pi);
    }
}

const: константа времени компиляции

const необходимо присвоить непосредственно заданное значение при объявлении; оно фиксируется во время компиляции. Такой член неявно является статическим.

using System;

class Circle
{
    public const double Pi = 3.14159;

    public static double Area(double r) => Pi * r * r;
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Circle.Area(2).ToString("0.00"));
    }
}

const должен быть литералом

Поскольку значение const определяется во время компиляции, оно может содержать только константное выражение: числа, строки, логические значения или другие константы.

using System;

class Limits
{
    public const int MaxRetries = 3;
    public const int Timeout = MaxRetries * 1000;   // const expression OK
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Limits.MaxRetries + ", " + Limits.Timeout);
    }
}

readonly: константа времени выполнения

Поле readonly задаётся один раз — при объявлении или в конструкторе — и после этого не может изменяться. Его значение можно вычислить во время выполнения.

using System;

class Session
{
    public readonly string Id;

    public Session(string id)
    {
        Id = id;   // allowed: inside constructor
    }
}

class Program
{
    static void Main()
    {
        var s = new Session("abc-123");
        Console.WriteLine("Session: " + s.Id);
    }
}

readonly может использовать значения времени выполнения

В отличие от const, поле readonly может содержать значение, известное только во время работы программы, например сгенерированный идентификатор или текущее время.

using System;

class Order
{
    public readonly Guid OrderId;

    public Order()
    {
        OrderId = Guid.NewGuid();
    }
}

class Program
{
    static void Main()
    {
        var o = new Order();
        Console.WriteLine("Has id: " + (o.OrderId != Guid.Empty));
    }
}

Статический readonly

Сочетайте static readonly, чтобы получить общее для класса значение, вычисляемое один раз во время выполнения. Обычно это замена const, когда значение не является литералом.

using System;

class AppInfo
{
    public static readonly string[] Roles = { "admin", "user", "guest" };
}

class Program
{
    static void Main()
    {
        Console.WriteLine("Roles: " + Roles());
    }

    static int Roles() => AppInfo.Roles.Length;
}

Почему константы могут быть рискованными в разных сборках

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

using System;

class Lib
{
    public const int Version = 2;              // inlined into callers
    public static readonly int Build = 100;     // read at runtime
}

class Program
{
    static void Main()
    {
        Console.WriteLine(Lib.Version + "." + Lib.Build);
    }
}

Ни одно из них нельзя переназначить

После инициализации ни поле const, ни поле readonly нельзя изменить. Попытка сделать это приводит к ошибке компиляции.

using System;

class Demo
{
    public const int A = 10;
    public readonly int B;

    public Demo() { B = 20; }
    // A = 11;  // would not compile
    // B = 21;  // would not compile outside constructor
}

class Program
{
    static void Main()
    {
        var d = new Demo();
        Console.WriteLine(Demo.A + ", " + d.B);
    }
}

Выбор между ними

Используйте const для настоящих литералов, которые никогда не меняются (число π, MaxInt). Используйте readonly, если значение вычисляется во время выполнения или может отличаться у разных экземпляров.

using System;

class Physics
{
    public const double Gravity = 9.81;          // universal literal
    public readonly double Mass;                  // per object

    public Physics(double mass) { Mass = mass; }
    public double Weight() => Mass * Gravity;
}

class Program
{
    static void Main()
    {
        var p = new Physics(10);
        Console.WriteLine("Weight: " + p.Weight());
    }
}

Нюанс readonly-ссылки

readonly блокирует поле, но не объект, на который оно указывает. Ссылку на список, объявленную как readonly, нельзя переназначить, но её содержимое по-прежнему можно изменить.

using System;
using System.Collections.Generic;

class Cart
{
    public readonly List<string> Items = new List<string>();
}

class Program
{
    static void Main()
    {
        var c = new Cart();
        c.Items.Add("Pen");   // allowed: mutating the object
        c.Items.Add("Book");
        Console.WriteLine("Items: " + c.Items.Count);
    }
}

Собираем всё вместе

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

using System;

class Account
{
    public const decimal MinBalance = 0m;
    public readonly string Owner;

    public Account(string owner)
    {
        Owner = owner;
    }
}

class Program
{
    static void Main()
    {
        var a = new Account("Rin");
        Console.WriteLine(a.Owner + " min=" + Account.MinBalance);
    }
}

Быстрая проверка

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

Итоги

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

using System;

class Demo
{
    public const int Max = 100;
    public readonly int Created;
    public Demo(int c) { Created = c; }
}

class Program
{
    static void Main()
    {
        var d = new Demo(7);
        Console.WriteLine(Demo.Max + ", " + d.Created);
    }
}

Часто задаваемые вопросы

Урок «Константы и поля readonly» бесплатный?

Да — полный текст урока «Константы и поля readonly» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Константы и поля readonly»?

Различайте const и static readonly. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Константы и поля readonly»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Статические методы и поля
  2. Статические классы для вспомогательных средств
  3. Константы и поля readonly
  4. Статические и экземплярные элементы
← Назад к C# Academy