Skip to main content

Property Accessors

Written by: Akram Taghavi-Burris | © Copyright 2024

Status: In Development

In C# a property accessors define how a class exposes its internal fields. To better understand this let's take a look at the individual definitions of these concepts.

  • Field : The direct variable inside a class, typically declared with an access modifier (private, public, etc.).

  • Property: The construct that provides controlled access to a field through accessors.

  • Accessor: The individual get or set block within a property.

Standard Usage

The standard approach to using property accessors is where both a getter and setter are explicitly defined, using a private field to store the value. The getter returns the value, and the setter modifies it. Below of how this is implemented:

Person.cs
public class Person
{
private string _name; // Private field

public string Name // Public property
{
get { return _name; } // Getter (accessor): Returns the value of _name
set { _name = value; } // Setter (accessor): Assigns a new value to _name
}
}

We can break the code above into the following elements:

  • _name is the field accessible only to this class as it is marked as private
  • Name is the public property which other classes can access, but to what extent?
  • get and set are the accessors. Which in this instance allows for the value the field to be viewed and for a new value to the filed to be set.
Understanding Fields and Properties

Have you ever been asked to fill out a survey or complete a form? Whether it was a digital form or an old-school paper one, you probably encountered a series of questions with little boxes where you had to type or write your answers.

Think of one of these boxes as a field, let's say it is labeled "Name." The field itself is just an empty container, waiting for someone to enter a value like "Bob" or "Sue".

Now, when it’s time to compile the responses, we are not interested in the textbox itself, instead we want the actual value that was entered. That's where properties come in! The property called Name lets us retrieve what was written in the box.

Interacting with Data

Just like some forms say "Do not write in this section", property accessors determine how we can interact with the data.

  • If the form is read-only, it’s like having a property with only a get accessor. We can read the value of Name, but that is all we can do.

  • If we notice a typo and need to correct it, this is where we could use set accessor, which allows the value of Name to be changed or updated.

  • And if a field is completely locked down with a private setter, this means only the form has access to the field textbox and the input value. No one outside the actual form has access to the data, and you’ll just have to live with your mistakes.

So next time you’re filling out a form, just remember: fields hold data, properties manage data, and accessors decide whether you're allowed to mess the data.

And if you ever get frustrated with a form that won’t let you correct your own name, just know, somewhere in the code, there are property accessors at work or in some cases not at work 😅 that limit your access.

Auto Backing Field

As in the previous examples a private field is defined and then a public property to access the field is defined.

However, since this field property relationship is very common, C# allows or a more concise way to define a property without manually creating a private field:

public string Name { get; set; }  // Auto-property (C# automatically creates a backing field)

In this example, the private backing field (like _name) is not explicitly declared because C# automatically creates it behind the scenes to store the value. You can think of this backing field as a memory location where the value of Name is stored.

In code, the backing field is never directly accessed. Instead, the value is always accessed through the property Name (using the get and set methods). While the backing field is not visible in your code, it exists internally to handle the storage of the value.

How to Use

If we take another look at the previous example, in which C# creates the backing field, and both a get and set accessor are applied to the property, it actually isn't really all that usefully.

public string Name { get; set; }  // Auto-property (C# automatically creates a backing field)

In fact the property we created could have simply been a public field as in the example below:

public string Name;

Okay, so why should we use property accessors at all? The real value of using property accessors is when we want to control to access (get/set) the property. In fact there are several different ways in which we can control access to properties, which include:

Read-Only Property

private string _name;

public string Name
{
get { return _name; }
}

Description:
A read-only property means the value can only be retrieved publicly through the get accessor. The private field (_name) can be set only within the class, typically in the constructor or other methods.


Read-Only | Auto Field

public string Name { get; private set; }

Name = "Bob";

Description:
This combines the auto backing field syntax with a private setter, allowing public access to the value via get but restricting the setter to within the class. The compiler automatically creates the backing field for storing the value.

Auto Backing Fields

Using the auto-backed field method with a private set, as shown in the example above, is perfectly valid. However, relying solely on the public property within the class might lead us to mistakenly believe that it's a public field accessible by all classes. While we could always scroll to the top of the code or check our IDE for clarification, manually defining a private field within the class ensures that we explicitly understand the field is encapsulated and not accessible from outside the class.


Write-Only Property

private string _password;

public string Password
{
set { _password = value; }
}

Description:
A write-only property has a setter but no getter, which is useful for cases like storing sensitive data (e.g., passwords) where the value is only set and not retrieved.


Custom Setter Logic

private string _age;

public string Age
{
get { return _age; }
set { if (value > 0) _age = value; }
}

Description:
This property adds custom logic in the setter, allowing validation before setting the value. In this case, the age can only be set to positive values.


Expression-Bodied Property

private string _score;

public string Score
{
get => _score;
set => _score = value;
}

Description:
An expression-bodied property is a shorthand syntax for properties where the getter and/or setter is a simple single expression. It's compact and typically used when there's no need for additional logic in the getter or setter.

Conclusion:

Each property style serves different purposes, from full control over getter/setter logic to more concise forms. Choose the one that fits the needs of your class and its logic.