C# > Language Features by Version > C# 6 to C# 12 Highlights > Init-only Properties (C# 9)

Init-Only Properties in C# 9

C# 9 introduced init-only properties, providing a way to initialize properties during object creation but preventing modification afterward. This enhances object immutability and improves code clarity.

Basic Init-Only Property

The init keyword allows a property to be set only during object initialization. Once the object is created, the property becomes read-only. Attempting to modify an init-only property after initialization results in a compile-time error.

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }

    public override string ToString()
    {
        return $"FirstName: {FirstName}, LastName: {LastName}";
    }
}

public class Example
{
    public static void Main(string[] args)
    {
        Person person = new Person { FirstName = "John", LastName = "Doe" };
        Console.WriteLine(person.ToString());

        // Compilation error: Cannot modify init-only property after object creation
        // person.FirstName = "Jane";
    }
}

Concepts Behind Init-Only Properties

Init-only properties bridge the gap between fully mutable and immutable objects. They allow for object customization during creation while guaranteeing that certain key properties remain constant throughout the object's lifecycle. This contributes to better object state management and thread safety.

Real-Life Use Case

Consider a configuration object where certain settings should only be defined during application startup. Using init-only properties ensures that these configurations are not accidentally modified during runtime, preventing unexpected behavior. For example a connection string, an API Key or some external configuration setting.

Best Practices

  • Use init-only properties for properties that should not change after object creation.
  • Combine init-only properties with constructor initialization for more complex object setup.
  • Avoid using init-only properties for properties that require frequent updates.

Interview Tip

Be prepared to explain the difference between get; set;, get; private set;, and get; init; properties. Understand the use cases for each and the benefits they provide in terms of encapsulation and immutability.

When to Use Them

Use init-only properties when you need to initialize a property during object creation and then prevent further modification. This is particularly useful for configuration settings, identifiers, or any data that represents a fixed characteristic of an object.

Memory Footprint

Init-only properties do not introduce any additional memory overhead compared to regular properties. They simply enforce a restriction on when the property can be set. The underlying storage is the same.

Alternatives

Before C# 9, you could achieve similar behavior using a constructor to set the property value and then only providing a getter. However, this approach is less discoverable and doesn't clearly communicate the intent that the property is only meant to be initialized during object creation. Another older alternative involved private setters and setting the values in the constructor. The key advantage with init is the object initializer syntax.

Pros

  • Improved Immutability: Enforces that a property cannot be changed after object creation.
  • Clear Intent: Explicitly communicates that a property is meant to be initialized during object creation.
  • Object Initializer Support: Allows using object initializers to set the property value.

Cons

  • Limited Flexibility: Cannot be used for properties that require frequent updates.
  • Requires C# 9 or Later: Not available in older versions of C#.

Example with Record Type

Records in C# are inherently immutable. init properties work perfectly with records to allow initialization using object initializer syntax. This provides a concise and safe way to create immutable data objects.

public record PersonRecord
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}

public class ExampleRecord
{
    public static void Main(string[] args)
    {
        PersonRecord person = new PersonRecord { FirstName = "John", LastName = "Doe" };
        Console.WriteLine($"FirstName: {person.FirstName}, LastName: {person.LastName}");
    }
}

FAQ

  • What is the difference between get; set; and get; init;?

    get; set; allows a property to be both read and written at any time. get; init; allows a property to be read at any time, but it can only be written during object initialization.
  • Can I use init-only properties in older versions of C#?

    No, init-only properties are a feature introduced in C# 9 and are not available in earlier versions.
  • Are init-only properties truly immutable?

    Init-only properties prevent direct modification of the property itself after initialization. However, if the property holds a reference to a mutable object (e.g., a List), the contents of that object can still be changed. To achieve true immutability, the object itself must be immutable.