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

«Может ли конструктор класса в C# принимать параметры?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, конструкторы в 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!