Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Declare and Initialize Read-only Auto Properties in C#

Mar 20, 2020 • 5 Minute Read

Introduction

Version 6 of C#, released in 2015 alongside Visual Studio ultimate, implemented a unique feature: The read-only auto-property, sometimes referred to as the getter-only auto-property. In this guide, we will take the concepts of fields and properties and see how both can be read-only and how they are implemented while focusing on the auto-property aspect. We will also see how this new feature gave developers more ways to overcome problems and challenges.

Fields vs. Properties

These two concepts revolve around the idea of abstraction. With a class, you can have fields and properties. Fields are normal variable members. Properties are abstractions that allow you to get or even set their values.

Let's look at an example of fields. We have a server ServerFieldDemo class with two members.

      public class ServerFieldDemo
{
    private string _Name;
    private string _Function;
    
    public ServerFieldDemo(string name, string function){
        this._Function = function;
        this._Name = name;
    }
}
    

When you define fields, you should make sure you define them as private as this ensures you are not violating the concept of encapsulation. Encapsulation, in short, means that you are bundling the fields or data with methods and functions that are capable of manipulating them without exposing them for direct manipulation. This current code is not sufficient as it is not able to retrieve these members.

In order to imbue our class with properties, also called accessors, modify the class in the following way.

      public class ServerFieldDemo
{
    private string _Name;
    private string _Function;
    public string Name { get { return _Name; } set {_Name = value; } }
    public string Function { get { return _Function; } set { _Function = value; } }

    public ServerFieldDemo(string name, string function){
        this._Function = function;
        this._Name = name;
    }
}
    

You now have the option to read and modify the properties. Call the code.

      ServerFieldDemo a = new ServerFieldDemo("pikkolo", "Domain Controller");
Console.WriteLine($"The name is: {a.Name} and function is: {a.Function}");
a.Name = "songoku";
a.Function = "DNS Server";
Console.WriteLine($"The name is: {a.Name} and function is: {a.Function}");
    

You should see the following output upon execution.

      he name is: pikkolo and function is: Domain Controller
The name is: songoku and function is: DNS Server
    

You have initialized the class with the help of the constructor, and the fields were changed with the help of the property accessors. You have obeyed the encapsulation principle, as well. Now that you clarified the concepts, spice it up with the read-only aspect.

To create a read-only field, use the readonly keyword in the definition.

      public class ServerFieldDemo
{
    readonly string _Name;
    readonly string _Function;
    
    public ServerFieldDemo(string name, string function){
        this._Function = function;
        this._Name = name;
    }
}
    

In the case of a field member, you get only one chance to initialize the field with a value, and that is when you call the class constructor. Beyond that, you'll would get an error for such attempt. The problem with the above class is that you cannot access the fields. You need to find a workaround for that. You still want to keep in mind the read-only aspect, so the property can only be retrieved for the class but not modified. With a little modification to the code, you can demonstrate this.

      public class ServerFieldDemo
{
    private string _Name;
    private string _Function;
    public string Name { get { return _Name; } }
    public string Function { get { return _Function; } }
    public ServerFieldDemo(string name, string function){
        _Name = name;
        _Function = function;
    }
}
    

Now take the class for a test drive.

      ServerFieldDemo a = new ServerFieldDemo("pikkolo", "Domain Controller");
Console.WriteLine($"The name: {a.Name}, function: {a.Function}");
    

The output of the code is as follows.

      The name: pikkolo, function: Domain Controller
    

If you attempt to rename the class like this ...

      a.Name = "New Name";
    

... the compiler will show the following error.

      CS0200	Property or indexer 'ServerFieldDemo.Name' cannot be assigned to -- it is read only	Pluralsight
    

The reason for this is that the setter was omitted from the property definition, and now you can only access but not modify the property deeper inside the field of the class.

This change allows you to keep the internal structure of the class intact and prevent any modifications. All in all, if you want to create read only properties, just omit the definition of the setter in that specific property while making sure the field stays private so you do not violate the principle of encapsulation.

Conclusion

In this guide, you learned about fields and propertiesand how they are related to each other, followed by how to protect data and integrity encapsulated in a class with the read-only concept. I hope this has been informative to you and I would like to thank you for reading it!