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 ?