C# tutorials > Modern C# Features > C# 6.0 and Later > What are init-only setters in C# 9.0 and when would you use them?
What are init-only setters in C# 9.0 and when would you use them?
C# 9.0 introduced init
-only setters, a feature that allows you to initialize a property during object creation but prevents it from being modified afterward. They provide a way to create immutable or semi-immutable objects, ensuring data integrity after initialization.
Understanding Init-Only Setters
In this example, the The Person
class has three properties: FirstName
, LastName
, and DateOfBirth
. All three properties are defined with the init
keyword. This means that these properties can be set during object initialization. However, once the object is created, these properties cannot be modified.Example
class demonstrates how to initialize a Person
object and then attempts to modify one of its init
-only properties. The commented-out line will cause a compilation error because you cannot change FirstName
after the object has been initialized. This helps create immutable aspects of your object, increasing its reliability.
public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
public DateTime DateOfBirth { get; init; }
public override string ToString()
{
return $"Name: {FirstName} {LastName}, Born: {DateOfBirth:d}";
}
}
public class Example
{
public static void Main(string[] args)
{
var person = new Person
{
FirstName = "John",
LastName = "Doe",
DateOfBirth = new DateTime(1990, 1, 1)
};
Console.WriteLine(person);
//The following line would cause a compilation error
//person.FirstName = "Jane";
}
}
Concepts Behind the Snippet
The core concept is controlled mutability. init
-only setters offer a middle ground between fully mutable properties (with standard get; set;
) and fully immutable properties (with only get;
). They allow initialization during object creation, providing a way to set values that should remain constant throughout the object's lifetime. This promotes the creation of more robust and predictable code.
Real-Life Use Case Section
Consider a configuration class where certain settings need to be defined at startup but should not be changed during runtime. Another practical case is with data transfer objects (DTOs) that represent data from an external source. These DTOs often benefit from having their properties initialized once and then treated as read-only. Also, when loading data from a database where primary keys should not be changed after being loaded into memory.
Best Practices
Use init
-only setters for properties that represent the initial state of an object or values that should not change after creation. Avoid using them for properties that are expected to be modified throughout the object's lifecycle. Consider using constructors to initialize properties when initialization logic is complex or requires validation.
Interview Tip
When discussing init
-only setters, highlight their role in creating immutable or semi-immutable objects and improving code maintainability. Explain their benefits for data integrity and how they promote defensive programming practices. Be prepared to discuss scenarios where they are most appropriate and how they differ from regular setters and read-only properties.
When to Use Them
Use init
-only setters when:
Memory Footprint
init
-only setters do not inherently impact the memory footprint compared to regular setters. The memory consumed by the properties themselves remains the same. The primary difference lies in the compile-time enforcement of immutability after initialization, which doesn't directly affect memory allocation.
Alternatives
Alternatives to init
-only setters include:get;
): Suitable for properties that are calculated or derived and should never be directly set.get; private set;
): Allow the property to be modified only within the class itself.
Pros
Cons
FAQ
-
Can I use init-only setters with structs?
Yes, you can useinit
-only setters with structs in C# 9.0 and later. This allows you to create immutable structs, which can be beneficial for performance and thread safety. -
How do init-only setters differ from private setters?
init
-only setters allow initialization only during object creation using an object initializer. Private setters allow modification of the property only within the class itself, but not from outside the class.init
restricts assignments to only object initialization time. -
Are init-only properties truly immutable?
init
-only properties are effectively immutable from the perspective of external users of the class after initialization. However, you need to consider the immutability of the *type* of the property. If the property is of a mutable reference type (like aList
), the *contents* of that referenced object can still be changed, even if the property itself cannot be reassigned to a different list. For true immutability, you would need to use immutable collections or defensive copying techniques.