Introduction
In this post, I show 6 ways to implement auto-implemented properties in C#. An auto-implemented property is a short-hand way to declare a property when there is no logic required in the accessors and it doesn't require a backing field.
Auto-Implemented Properties
A traditional property with a backing field looks like this.
private string _name; // field
public string Name // property
{
get { return _name; }
set { _name = value; }
}
This property doesn't require any logic in the get
or set
accessor. The first way to shorten it is to make it an auto-implemented property like this
public string Name { get; set; }
This is probably the most common way to declare auto-implemented properties in C# but it has it's drawbacks. It is mutable because the value can be set from anywhere and no default value means it could be null
when an instance is created.
A second way to declare the auto-implemented property is to assign a default value. This is still mutable but will have a value if not set when an object is instantiated.
public string Name { get; set; } = string.Empty;
Another way to declare the auto-implemented property is to change the access level of set
to private set
so it can only be updated from the object's constructor.
public string Name { get; private set; }
The example above requires the object to have a constructor to provide a value. A similar option is available but allows the value to be set when the object is initialized.
// Set only allowed during object initialization
public string Name { get; init; }
// Instantiate an object
public class Person
{
public string Name { get; init; }
}
public static void main(strings[] args)
{
var person = new Person()
{
Name = "Test Name" // Name can only be set here.
}
p.Name = "Updated Name"; // Compilation error because Name cannot be changed outside of the object initializer.
}
This can also be expanded to include a default value as well
public string Name { get; init; } = string.Empty;
Finally, if the property is required but a default value doesn't make sense, the required
keyword can be added. This would produce a compilation error if an object is initialized without the property being set to a value.
// Set only allowed during object initialization
public required string Name { get; init; }
// Instantiate an object
public class Person
{
public required string Name { get; init; }
}
public static void main(strings[] args)
{
var person = new Person(); // Compilation error because `Name` is not set to a value
// Valid
var person = new Person()
{
Name = "Test Name" // Name must have a value and can only be set here.
}
}
Conclusion
In conclusion, there are many ways to set auto-implemented properties. Each one has it's benefits and drawbacks depending on the purpose of the class and how it is used. I find the varying options useful when I want values to be immutable, required, or to avoid null values.
Top comments (1)
Using
private set
doesn't mean the property can only be set via the constructor. It can be set from anywhere inside the instance. This is still a mutable property, only you now have full control over its set calls:If you want an immutable property, you can use a get-only property (meaning it has to be initialized either directly or from a constructor) or a get/init property (so it can also be initialized from object initialization: