In C# 12, Microsoft introduced Primary Constructors for classes and structs, effectively making code cleaner and reducing the amount of redundant "assigning parameters to private fields" we’ve done for decades.
In legacy C#, 50% of your class was just boilerplate for Dependency Injection. Primary constructors allow you to define parameters directly on the class header.
public class Service
{
private readonly IRepository _repo;
public Service(IRepository repo)
{
_repo = repo;
}
}
// The parameter 'repo' is available throughout the whole class body!
public class Service(IRepository repo)
{
public async Task DoWork() => await repo.Save();
}
Sometimes you don't want a constructor at all, but you want to FORCE the developer to set a property when they create the object. We use the required keyword.
public class User
{
public required string Email { get; init; }
public string? OptionalNickName { get; set; }
}
// ❌ ERROR: Compiler yells because 'Email' was not set
var u = new User();
// ✅ GOOD
var u = new User { Email = "sandeep@example.com" };
Q: "If I use a Primary Constructor on a class, why can't I access the parameter from outside the class instance?"
Architect Answer: "Primary constructor parameters in classes are NOT properties or fields; they are purely parameters with a 'Class-wide' scope. The compiler captures them privately. If you want a primary constructor parameter to be publicly visible, you must manually assign it to a public property inside the class body. This is a deliberate security feature to avoid 'accidental exposure' of injected services (`DbContext`, `Logger`) which should remain private internal implementation details."