Когда вызывается конструктор в C#?

Ответ

Конструктор вызывается автоматически в момент создания экземпляра класса с помощью оператора new. Его основная задача — привести объект в валидное начальное состояние, проинициализировав поля и свойства.

Базовый пример:

public class Order
{
    public int Id { get; }
    public DateTime CreatedAt { get; }

    // Конструктор экземпляра
    public Order(int id)
    {
        Id = id;
        CreatedAt = DateTime.UtcNow; // Инициализация при создании
    }
}

// Вызов конструктора при инстанцировании
var newOrder = new Order(1001);

Ключевые моменты и типы конструкторов:

  1. Конструктор по умолчанию: Если в классе нет ни одного конструктора, компилятор C# автоматически генерирует публичный конструктор без параметров.
  2. Статический конструктор: Вызывается один раз перед первым обращением к классу (до создания первого экземпляра или использования любого статического члена). Используется для инициализации статических полей.
    public class Logger
    {
        static Logger()
        {
            // Инициализация статического конфигурационного поля
            LogLevel = ConfigurationManager.AppSettings["DefaultLogLevel"];
        }
        public static string LogLevel { get; }
    }
  3. Цепочка конструкторов: Конструктор производного класса должен явно или неявно вызывать конструктор базового класса с помощью : base(...).
  4. Приватный конструктор: Используется в паттернах, запрещающих создание экземпляров (например, в статических классах или для реализации Singleton).

Ответ 18+ 🔞

Давай разжую эту тему про конструкторы, как будто я тебе на кухне объясняю, пока чайник кипит.

Смотри, конструктор — это как ритуал посвящения для нового объекта. Только родился экземпляр класса — сразу получает по шапке от конструктора, который настраивает его на правильную жизнь. Вызывается этот ритуал автоматом, когда ты пишешь волшебное слово new.

Проще говоря:

var newOrder = new Order(1001); // Вот тут, в момент 'new', и вызовется конструктор

А теперь по типам, как они в жизни бывают:

  1. Обычный, дефолтный конструктор. Если ты в классе нихуя не написал, компилятор, такой добрый дядя, сам подсовывает тебе пустой публичный конструктор. Но стоит тебе написать свой с параметрами — этот невидимый помощник исчезает, и если тебе потом вдруг понадобится конструктор без параметров, придётся его вписывать руками. Распиздяйство, но так устроено.

  2. Статический конструктор — это отдельная песня. Вызывается он один раз за всю жизнь программы, когда классу впервые понадобилось проявиться. Неважно, создаёшь ты экземпляр или просто ткнул в статическое поле. Он как старый дед, который один раз настраивает фамильные ценности (статические поля), а потом все наследники этим пользуются.

    public class Logger
    {
        static Logger()
        {
            // Сделаем это один раз и навсегда, блядь
            LogLevel = ConfigurationManager.AppSettings["DefaultLogLevel"];
        }
        public static string LogLevel { get; }
    }
  3. Цепочка вызовов — семейное дело. Когда у тебя есть наследник (производный класс), его конструктор обязан позвать папу (конструктор базового класса). Или явно через : base(...), или неявно — тогда позовётся дефолтный конструктор родителя. Иначе — компоновка не сойдётся, и компилятор начнёт материться.

  4. Приватный конструктор — для избранных. Сделал конструктор приватным — и всё, обычные смертные экземпляры создать не могут. Используется для всяких хитрожопых паттернов вроде Singleton (чтобы экземпляр был один, как всемирное тяготение) или для чисто статических классов-утилит, где объекты вообще не нужны.

Короче, конструктор — это твой первый и главный инструмент, чтобы объект родился не куском бесформенного кода, а сразу при делах, с проинициализированными полями и готовый к работе. Не забывай про это, а то получится как в той поговорке: родился в сраке, а претензии ко всем.