What are primary constructors in C# 12?

C# Language Features Basic 1–2 Yrs2–3 Yrs Conceptual 1 min read

Quick Answer

Primary constructors (C# 12) let you declare constructor parameters right on the class/struct declaration — class OrderService(IOrderRepository repo, ILogger<OrderService> logger) — and those parameters are in scope throughout the class body. It removes the boilerplate of a constructor that just assigns injected dependencies to fields.

Primary constructors let me put the constructor parameters on the class declaration itself, and then use them anywhere in the class. For a service with five injected dependencies, instead of five private readonly fields plus a constructor that assigns them, I just write class OrderService(IOrderRepo repo, ILogger logger) and use repo and logger directly. Unlike a record, the parameters don't become public properties — they're just captured as fields if I use them. It's purely a boilerplate reducer for dependency-injection-heavy classes.

  • The parameters aren't automatically properties (unlike a record) — they're captured as hidden fields only if used.
  • Great for DI-heavy classes: no more private readonly IFoo _foo; public Ctor(IFoo foo) => _foo = foo; ×5.
  • You can still add other constructors, but they must chain to the primary one with : this(...).
  • Records had primary constructors already; C# 12 brought them to plain classes and structs.