C# Property

Summary: in this tutorial, you’ll about the C# property and how to use the properties effectively.

Introduction to the C# property

By definition, a property is a member of a class that provides a flexible way to read, write, or compute the value of a private field.

For example, the following defines the class Person with three private fields firstName, lastName, and age:

// Person.cs class Person { private string firstName; private string lastName; private int age; }Code language: C# (cs)

To assign values to and read values from these private fields, you use properties. The following shows how to add three properties to the Person class:

// Person.cs class Person { private string firstName; private string lastName; private int age; public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public int Age { get { return age; } set { age = value; } } }Code language: C# (cs)

In this example, we declare a property like a field with a get and set blocks. The get and set are called the property accessors.

When you read from a property, the get accessor executes. And when you assign a value to a property, the set accessor executes. For example:

// Program.cs var p1 = new Person(); p1.FirstName = "John"; p1.LastName = "Doe"; Console.WriteLine($"{p1.FirstName} {p1.LastName}");Code language: C# (cs)

In this example:

  • First, create an instance of the Person class.
  • Second, assign the values to the FirstName and LastName properties.
  • Third, read values from the FirstName and LastName properties.

Using C# property for data validation

Since a property provides a central place to assign a value to a private field, you can validate the data and throw an exception if the data is not valid.

Suppose you want to implement the following validation rules:

  • The first name and last name are not null or empty
  • The age is between 1 and 150

To do that, you can add the validation logic to the set accessors of the properties as shown in the following example:

// Person.cs class Person { private string firstName; private string lastName; private int age; public string FirstName { get { return firstName; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentException("The first name must not be empty or null"); } firstName = value; } } public string LastName { get { return lastName; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentException("The last name must not be empty or null"); } lastName = value; } } public int Age { get { return age; } set { if (value < 0 || value > 150) { throw new ArgumentException("The age must be between 1 and 150"); } age = value; } } }Code language: C# (cs)

The following program causes an exception because the age is out of the valid range (1-150)

// Program.cs var p1 = new Person(); p1.FirstName = "John"; p1.LastName = "Doe"; p1.Age = 200; // cause an exceptionCode language: C# (cs)

Output:

Unhandled exception. System.ArgumentException: The age must be between 1 and 150Code language: C# (cs)

C# computed property

To create a computed property, you can implement the get accessor. For example, you can create a FullName property that returns the concatenation of the first name and last name:

// Person.cs class Person { private string firstName; private string lastName; private int age; public string FirstName { get { return firstName; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentException("The first name must not be empty or null"); } firstName = value; } } public string LastName { get { return lastName; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentException("The last name must not be empty or null"); } lastName = value; } } public int Age { get { return age; } set { if (value < 0 || value > 150) { throw new ArgumentException("The age must be between 1 and 150"); } age = value; } } public string FullName { get { return $"{FirstName} {LastName}"; } } }Code language: C# (cs)

And you can read from the FullName property:

// Program.cs var p1 = new Person(); p1.FirstName = "Jane"; p1.LastName = "Doe"; p1.Age = 25; Console.WriteLine(p1.FullName);Code language: C# (cs)

Output:

Jane DoeCode language: C# (cs)

If you attempt to assign a value to the FullName property, you’ll get a compilation error. For example:

// Program.cs var p1 = new Person(); p1.FirstName = "Jane"; p1.LastName = "Doe"; p1.Age = 25; Console.WriteLine(p1.FullName); p1.FullName = "Jane Smith";Code language: C# (cs)

Error:

Property or indexer 'Person.FullName' cannot be assigned to -- it is read onlyCode language: C# (cs)

C# auto-implemented properties

If you have a property that requires no additional logic in the set or get accessors, you can use an auto-implemented property.

The following example defines the Skill class that has two private fields name and rating, and the corresponding properties:

class Skill { private string name; private sbyte rating; public string Name { get { return name; } set { name = value; } } public sbyte Rating { get { return rating; } set { rating = value; } } }Code language: C# (cs)

Since the accessors of the properties have no additional logic besides reading from and writing to private fields, you can use auto-implemented properties like this:

class Skill { public string Name { get; set; } public sbyte Rating { get; set; } }Code language: C# (cs)

When the C# compiler encounters an auto-implemented property, it creates a private, anonymous field that can be accessed through the set and get accessors.

As you can see, the auto-implemented properties make the code more concise in this case.

In C# 9 or later, you can init an auto-implemented property like this:

class Skill { public string Name { get; set; } public sbyte Rating { get; set; } = 1; }Code language: C# (cs)

In this example, we initialize the Rating property so that its value is one when you create a new instance of the Skill class.

Summary

  • A property is a member of a class that provides a flexible way to read, write, or compute the value of a private field.
  • A property contains get and/or set accessors.
  • The get accessor executes when you read the value from the property while the set accessor executes when you assign a value to the property.
  • Use auto-implemented property if the get and set accessors have no additional logic to make the code more concise.
Was this tutorial helpful ?