← Назад к вопросам
Как можно присвоить значения полям, которые помечены 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
| Характеристика | const | readonly |
|---|---|---|
| Инициализация | Только при объявлении | При объявлении или в конструкторе |
| Время компиляции | Вычисляется на компиляции | Вычисляется на 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); // Неизменяемый тип