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

Как можно присвоить значения полям, которые помечены readonly? В чём разница между const и readonly?

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

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Как присвоить значения readonly полям? Разница между const и readonly

Присвоение значений readonly полям

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

1. При объявлении (initializer)

public class User
{
    private readonly string _name = "DefaultName";
    public readonly int MaxRetries = 3;
}

2. В конструкторе класса

public class Configuration
{
    public readonly string ApiKey;
    public readonly int Timeout;

    public Configuration(string apiKey, int timeout)
    {
        ApiKey = apiKey;      // OK - присвоение в конструкторе
        Timeout = timeout;     // OK - присвоение в конструкторе
    }
}

var config = new Configuration("secret-key", 5000);
// config.ApiKey = "new-key";  // ОШИБКА - нельзя менять после создания

3. В init-только свойствах (C# 9+)

public class Point
{
    public int X { get; init; }
    public int Y { get; init; }
}

var p = new Point { X = 10, Y = 20 };  // OK - инициализация
// p.X = 30;  // ОШИБКА

Разница между const и readonly

Характеристикаconstreadonly
ИнициализацияТолько при объявленииПри объявлении или в конструкторе
Время компиляцииВычисляется на компиляцииВычисляется на runtime
ТипПримитивы, enum, строкиЛюбой тип
StaticВсегда static (неявно)Может быть instance или static
Область видимостиПубличная по умолчаниюКонтролируется модификаторами
ПроизводительностьМаксимальная (inline)Чуть медленнее

Примеры с const

public class Constants
{
    // const - компилируется в значение
    public const int MaxConnections = 100;
    public const string AppName = "MyApp";
    public const double Pi = 3.14159;
    
    // const всегда static
    // Constants.MaxConnections - доступ через класс, не через экземпляр
}

// В скомпилированном коде эти значения заменяются напрямую (inline)
int value = Constants.MaxConnections;  // Компилируется как: int value = 100;

Примеры с readonly

public class DatabaseConnection
{
    // readonly поле - инициализируется в конструкторе
    private readonly string _connectionString;
    public readonly DateTime CreatedAt;
    
    public DatabaseConnection(string connString)
    {
        // Можем присвоить в конструкторе
        _connectionString = connString;
        CreatedAt = DateTime.UtcNow;
    }

    public void Connect()
    {
        // Используем readonly значение
        Console.WriteLine($"Connecting to {_connectionString}");
    }
    
    // _connectionString = "new-string";  // ОШИБКА вне конструктора
}

var conn = new DatabaseConnection("Server=localhost");
conn.Connect();  // OK
// conn.CreatedAt = DateTime.Now;  // ОШИБКА

Практический пример

public class ApiClient
{
    // const - жёсткие пределы
    private const int MaxRetries = 3;
    private const string BaseUrl = "https://api.example.com";
    
    // readonly - конфигурируемые параметры
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly string _apiKey;
    private readonly int _timeout;

    public ApiClient(IHttpClientFactory factory, string apiKey, int timeout = 5000)
    {
        _httpClientFactory = factory;
        _apiKey = apiKey;
        _timeout = timeout;
    }

    public async Task<T> GetAsync<T>(string endpoint)
    {
        for (int i = 0; i < MaxRetries; i++)  // const используется как жёсткий лимит
        {
            try
            {
                var client = _httpClientFactory.CreateClient();
                client.Timeout = TimeSpan.FromMilliseconds(_timeout);  // readonly параметр
                
                var url = $"{BaseUrl}/{endpoint}";  // const строка используется
                var response = await client.GetAsync(url);
                
                return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
            }
            catch (HttpRequestException)
            {
                if (i == MaxRetries - 1) throw;
            }
        }
        
        return default;
    }
}

Когда использовать?

const — для неизменяемых констант, которые известны на момент компиляции:

  • Математические константы (Pi, E)
  • Числовые лимиты
  • Строковые литералы

readonly — для значений, которые:

  • Устанавливаются в конструкторе
  • Зависят от параметров конструктора
  • Могут быть разными для разных экземпляров
  • Объекты и сложные типы

readonly свойства (init) — для иммутабельных данных в С# 9+:

public record User(string Name, int Age);  // Неизменяемый тип
Как можно присвоить значения полям, которые помечены readonly? В чём разница между const и readonly? | PrepBro