ZetCode

C# Property

last modified April 24, 2021

C# Property tutorial shows how to work with properties in C#.

A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field.

Properties use accessors through which the values of the private fields can be read, written or manipulated. Property reads and writes are translated to get and set method calls. Properties shield the data from the outside world while having a convenient field access.

A get property accessor is used to return the property value, and a set property accessor is used to assign a new value. The init property accessor is used to assign a new value only during object construction. The value keyword is used to define the value that is assigned by the set or init accessor.

Properties can be read-write (they have both a get and a set accessor), read-only (they have only a get accessor), or write-only (they have only a set accessor).

C# Property with backing field

The following example uses a property with a backing field.

Program.cs
using System;

var u = new User();
u.Name = "Jane";

Console.WriteLine(u.Name);

class User
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

We have the Name property with the _name backing field.

var u = new User();
u.Name = "Jane";
    
Console.WriteLine(u.Name);

We create an instance of the User class. We access the member field using the field notation.

public string Name
{
   ...
}

We have a property that is called Name. It looks like a regular method declaration. The difference is that it has specific accessors called get and set.

get { return _name; }
set { _name = value; }

The get property accessor is used to return the property value and the set accessor is used to assign a new value. The value keyword is used to define the value being assigned by the set accessor.

C# read-only property

To create a read-only property, we omit the set accessor and provide only the get accessor in the implementation.

Program.cs
using System;

var u = new User("John Doe", "gardener");
Console.WriteLine(u);

class User
{
    private string _name;
    private string _occupation;

    public User(string name, string occupation)
    {
        _name = name;
        _occupation = occupation;
    }

    public string Name
    {
        get { return _name; }
    }

    public string Occupation
    {
        get { return _occupation; }
    }

    public override string ToString()
    {
        return $"{_name} is a {_occupation}";
    }
}

In the example, we have read-only properties. Once initialized in the constructor, they cannot be modified.

public string Name
{
    get { return _name; }
}

We make the property read-only by providing a get accessor only.

C# auto-implemented properties

C# has auto-implemented or automatic properties. With automatic properties, the compiler transparently provides the backing fields for us.

Program.cs
using System;

var u = new User();
u.Name = "John Doe";
u.Occupation = "gardener";

Console.WriteLine($"{u.Name} is a {u.Occupation}");

class User
{
    public string Name { get; set; }
    public string Occupation { get; set; }
}

This code is much shorter. We have a User class in which we have two properties: Name and Occupation.

var u = new User();
u.Name = "John Doe";
u.Occupation = "gardener";
    
Console.WriteLine($"{u.Name} is a {u.Occupation}");

We normally use the properties as usual.

public string Name { get; set; }
public string Occupation { get; set; }

Here we have two automatic properties. There is no implementation of the accessors and there are no member fields. The compiler will do the rest for us.

$ dotnet run
John Doe is a gardener

C# init-only property

The init keyword is used to create init-only properties; these properties can be initialized only during object construction.

Program.cs
using System;

var u = new User("John Doe", "gardener");
Console.WriteLine(u);

class User
{
    public User(string name, string occupation)
    {
        Name = name;
        Occupation = occupation;
    }

    public string Name { get; init; }
    public string Occupation { get; init; }

    public override string ToString()
    {
        return $"{Name} is a {Occupation}";
    }
}

We define two init-only properties; they are initialized inside the constructor. Later, they become immutable.

public string Name { get; init; }
public string Occupation { get; init; }

The init-only properties are created with the init keyword.

C# expression body definitions

Properties can be simplified with expression body definitions. Expression body definitions consist of the => symbol followed by the expression to assign to or retrieve from the property.

Program.cs
using System;

var u = new User("John Doe", "gardener");
Console.WriteLine($"{u.Name} is a {u.Occupation}");

class User
{
    private string _name;
    private string _occupation;

    public User(string name, string occupation)
    {
        Name = name;
        Occupation = occupation;
    }

    public string Name
    {
        get => _name;
        set => _name = value;
    }

    public string Occupation
    {
        get => _occupation;
        set => _occupation = value;
    }
}

In the example, we use the expression body definitions to define properties for the User class.

$ dotnet run
John Doe is a gardener

Other notes

We can mark properties with access modifiers like public, private or protected. Properties can be also static, abstract, virtual and sealed. Their usage is identical to regular methods.

Program.cs
using System;

var bs = new Base();
var dr = new Derived();

Console.WriteLine(bs.Name);
Console.WriteLine(dr.Name);
       
class Base
{
    protected string _name = "Base class";

    public virtual string Name
    {
        set { _name = value; }
        get { return _name; }
    }
}

class Derived : Base
{
    protected new string _name = "Derived class";

    public override string Name
    {
        set { _name = value; }
        get { return _name; }
    }
}

In the preceding example, we define a virtual property and override it in the Derived class.

public virtual string Name
{
    set { _name = value; }
    get { return _name; }
}

The Name property is marked with the virtual keyword.

protected new string _name = "Derived class";

We are hiding a member in the Derived class. To suppress the compiler warning, we use the new keyword.

public override string Name
{
    set { _name = value; }
    get { return _name; }
}

And here we override the Name property of the Base class.

In this tutorial, we have covered C# properties.