Getter-only autoproperties?

 •  Filed under C#, Programming, Roslyn

Sparked by a recent question on Stack Overflow, I thought I’d write up a post about this topic, both for my own reminder later and also to ensure I understand the concepts myself.

In this article I’ll dissect autoproperties in C# with only a getter, and how/why they can be written to in a constructor.

The topic of this question is code like this:

public class Foo
{
    public int Bar { get; }
    public Foo()
    {
        Bar = 5;
    }
}

Here’s some typical questions:

  • If the property doesn’t have a setter, how was I able to set it in the constructor?
  • Did the compiler add a private setter for me?
  • Is this really immutable?

The answer lies in how the C# compiler automagically rewrote the above code.

You can see the above code in its real form by using SharpLab, try it now.

The code that the compiler generates looks like this:

public class Foo
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    [CompilerGenerated]
    private readonly int <Bar>k__BackingField;
    public int Bar
    {
        [CompilerGenerated]
        get
        {
            return this.<Bar>k__BackingField;
        }
    }
    public Foo()
    {
        this.<Bar>k__BackingField = 5;
    }
}

Here are the important bits:

  • The compiler silently added a backing field. It gave it a name that syntactically isn’t legal C#, to avoid a collision with any backing fields provided by the programmer.
  • This backing field is declared as readonly, making the class immutable.
  • The getter is rewritten to return the value of this backing field.
  • The constructor is also rewritten to write to the backing field instead of the property. * This “circumvents” the issue of not having a setter for the property, you’re not really setting the property directly, but setting the backing field.

So there you have it. There’s a bit of magic going on, but being able to not have to declare and deal with the backing field makes writing immutable classes much easier.