DEV Community

Carl Layton
Carl Layton

Posted on

6 Options to Implement Auto-Implemented Properties

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; }
}
Enter fullscreen mode Exit fullscreen mode

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; }
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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; }
Enter fullscreen mode Exit fullscreen mode

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; }
Enter fullscreen mode Exit fullscreen mode
// 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.
}
Enter fullscreen mode Exit fullscreen mode

This can also be expanded to include a default value as well

public string Name { get; init; } = string.Empty;
Enter fullscreen mode Exit fullscreen mode

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; }
Enter fullscreen mode Exit fullscreen mode
// 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.
    }
}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
peledzohar profile image
Zohar Peled •

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:

public class Person
{
    public string Name {get; private set;}
    public void ChangeName(string newName) => Name = newName;
}
Enter fullscreen mode Exit fullscreen mode

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:

public class Person
{
    public Person(string firstName) => FirstName = firstName;
    public string FirstName {get;}
    public string MiddleName {get;} = "";
    public string LastName {get;init;}
}

var me = new Person("Zohar") {LastName = "Peled"};
Enter fullscreen mode Exit fullscreen mode