Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A primary constructor in C# is a concise syntax for declaring constructor parameters directly on a class or struct declaration. Introduced in C# 12, it scopes the declared parameters to the entire body of the type, allowing them to be used for field initialization, property assignment, or base class invocation without requiring a separate, explicitly defined constructor body.
public class TypeName(Type param1, Type param2)
{
    // param1 and param2 are available throughout the class body
}

Parameter Semantics and Scope

Unlike primary constructors on record types, parameters declared on a standard class or struct do not automatically generate public properties. Instead, they behave as parameters that are in scope throughout the entire instance declaration. The compiler determines how to allocate memory for these parameters based on their usage:
  1. Initialization Only: If a parameter is used exclusively to initialize a field or property, it is consumed during object construction, and the compiler does not generate a backing field for the parameter itself.
  2. Member Capture: If a parameter is referenced within a method, an accessor, or a lambda expression, the compiler automatically generates a private, mutable backing field to capture and store the parameter’s state for the lifetime of the object.
public class StateManager(int initialCapacity, string stateName)
{
    // Consumed during initialization; no backing field generated for 'initialCapacity'
    public int Capacity { get; set; } = initialCapacity;

    // Captured by a method; compiler generates a hidden backing field for 'stateName'
    public void PrintState() => Console.WriteLine(stateName);
    
    // Primary constructor parameters are mutable within the class body
    public void MutateState(string newName) => stateName = newName; 
}

Base Class Invocation

When a derived class utilizes a primary constructor, any required base class constructor arguments are passed directly in the inheritance declaration.
public class BaseEntity(Guid id)
{
    public Guid Id { get; } = id;
}

// 'id' is passed to the base constructor
public class UserEntity(Guid id, string username) : BaseEntity(id)
{
    public string Username { get; } = username;
}

Constructor Chaining Rules

When a type defines a primary constructor, it becomes the designated master constructor for that type. Any explicitly defined secondary constructors must invoke the primary constructor using the this(...) initializer. This ensures that the primary constructor parameters are always guaranteed to be initialized.
public class Configuration(string environment, int timeout)
{
    // Secondary constructor chaining to the primary constructor
    public Configuration(string environment) : this(environment, 30)
    {
        // Additional secondary constructor logic
    }

    // Parameterless constructor chaining to the primary constructor
    public Configuration() : this("Development", 30)
    {
    }
}

Struct-Specific Behavior

When applying a primary constructor to a struct, the compiler enforces standard struct initialization rules. The implicit parameterless constructor remains available and will initialize the struct to its default state (zeroing out memory), bypassing the primary constructor entirely unless explicitly invoked.
Master C# with Deep Grasping Methodology!Learn More