Primary constructors

C# 12.0 .NET 8.0

Published Updated Author Jeffrey T. Fritz Reading time

Declare constructor parameters directly in the class declaration, eliminating the need for explicit constructor bodies and field assignments.

Primary constructors, introduced in C# 12.0 (.NET 8.0), allow you to declare constructor parameters in the class declaration itself. These parameters automatically become field or property members of the class. This feature reduces ceremony for classes with simple initialization logic and brings the convenience of record-style initialization to regular classes.

Why it matters

  • Dramatically reduces boilerplate for simple classes with constructor parameters.
  • Improves readability by declaring and initializing state in one place.
  • Works seamlessly with inheritance and other class features.
  • Makes simple data-holding classes more concise without requiring full record syntax.

Cautions

  • Primary constructor parameters are accessible throughout the class body but are not automatically properties; assign them to properties explicitly if you need public access.
  • If you declare an explicit constructor, primary constructor parameters are no longer directly accessible unless you explicitly forward them.
  • Inheritance requires careful handling; derived classes must call the base primary constructor via the explicit : base(...) syntax.
  • Primary constructors only initialize what you explicitly assign; don’t assume automatic properties are created.

Declare and initialize properties inline

Primary constructors let you declare constructor parameters directly in the class declaration, automatically creating and initializing backing fields.

Valid since C# 12.0

Without var

public class Person
{
    private string name;
    private int age;

    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public string GetName() => name;
}

With var

public class Person(string name, int age)
{
    private string Name => name;
    private int Age => age;

    public string GetName() => Name;
}

Record-like initialization without records

Primary constructors bring record-style initialization convenience to regular classes, reducing boilerplate while maintaining explicit class semantics.

Valid since C# 12.0

var person = new Person("Alice", 30);
Console.WriteLine(person);

public class Person(string name, int age)
{
    public string Name { get; } = name;
    public int Age { get; } = age;

    public override string ToString() => $"{Name} ({Age} years old)";
}

Learn more

Primary constructors (Microsoft Learn)