Ответ
Да, конструкторы в C# могут и часто должны принимать параметры. Это основной способ обеспечения инвариантов объекта — гарантии того, что объект создаётся в валидном состоянии.
Базовый пример параметризованного конструктора:
public class Order
{
public string Id { get; }
public decimal Amount { get; }
public DateTime CreatedAt { get; }
// Конструктор с параметрами обеспечивает обязательную инициализацию
public Order(string id, decimal amount)
{
if (string.IsNullOrWhiteSpace(id))
throw new ArgumentException("Order ID cannot be empty", nameof(id));
if (amount <= 0)
throw new ArgumentException("Order amount must be positive", nameof(amount));
Id = id;
Amount = amount;
CreatedAt = DateTime.UtcNow; // Инициализация с логикой по умолчанию
}
}
// Использование: объект нельзя создать без обязательных данных
var order = new Order("ORD-12345", 99.99m);
Важные аспекты и best practices:
- Конструктор по умолчанию: Если вы объявляете любой конструктор с параметрами, компилятор не генерирует конструктор по умолчанию (без параметров). Добавить его нужно явно:
public Order() {}. - Перегрузка конструкторов: Можно определить несколько конструкторов с разными наборами параметров.
- Валидация: Конструктор — идеальное место для проверки входных аргументов и выброса
ArgumentExceptionпри невалидных данных. - Иммутабельность: Часто используется для инициализации свойств
get-only (только для чтения), что делает объект неизменяемым (immutable). - Внедрение зависимостей (DI): Параметризованные конструкторы — стандартный способ внедрения зависимостей в ASP.NET Core и других DI-контейнерах.
Сравнение с инициализаторами объектов:
// Параметризованный конструктор (предпочтительно для обязательных полей)
var user1 = new User("john.doe@example.com", "John");
// Конструктор по умолчанию + инициализатор (гибкость, но может оставить объект в невалидном состоянии)
var user2 = new User { Email = "john.doe@example.com" }; // Name может остаться null!