ReadOnly Auto-Properties (C# Wishes Part 2)

I’ve been talking on this blog talking about things I’d love to see added to C# – things that I think would give a significant improvement in the language. And my 2nd item is a very simple one: Allow read-only auto-properties.

Let’s look at the problem first.

If I want a read-only field and an encapsulating property, then it’s easy to achieve that if I do it the long way.

private readonly int _myValue;

public int MyValue { get { return _myValue;}}

The readonly keyword clearly declares my intention, and also enables the compiler to make sure I stick to it. The readonly keyword applied to a field will cause the compiler to generate an error if I try to set that field outside a constructor. In other words, it guarantees that, once the object has been instantiated, the value of that field can never change.

If I prefer to simplify my code by using an auto-property, the best I can do is this:

public int MyValue { get; private set;}

The private set makes sure that no code outside the class can directly modify the value, but it still allows code within the class to change the value at any time after construction. I just have to trust myself, as the author of the class, to avoid calling the setter except from inside the constructors. And the only way to make my intentions clear is with a comment.

// Do not call the setter except in the constructor 
public int MyValue { get; private set;}

I’m sure you don’t need me to spell out why, as ways of stating your intention go, this is not exactly ideal. If compilers could read English and understand and act on comments, it’d be brilliant. But somehow I suspect that building in a complete English language interpreter is not on Microsoft’s to-do list for the next Visual Studio!

The solution to this problem is very simple: Allow the readonly keyword to be applied to auto-properties in the same way they can be applied to fields:

public readonly int MyValue { get; private set;}

The meaning would be analogous to fields. You can’t call the setter except in the constructor. The intention is clearly declared and compiler-enforced. Perfect! Obviously a corollary is the setter of a read-only auto-property must be private – with the compiler flagging an error if it isn’t.

As language changes go, implementing this in the compiler must surely be about as simple as a language change is possible to be. And I know I’m not the first person to want this feature. Just look at Jon Skeet’s rather forthright answer to this StackOverflow question!

At this point I should be honest and admit that personally my feelings about auto-properties are mixed. I use them. In fact, I find them extremely useful for quickly proto-typing a class, but their inability to distinguish internal state from public interface tends to leave a bit of a bad taste in my mouth. And in my code, auto-properties often don’t survive the transition from prototype to actual production code. But on the other hand, I know a lot of other developers do like auto-properties and use them a lot. And allowing auto-properties to be read-only would definitely make them more useful, both to regular users and to occasional users like me. Maybe it’d even encourage me to use them a little bit more. So go on Microsoft…


2 thoughts on “ReadOnly Auto-Properties (C# Wishes Part 2)

  1. Could there be a case for allowing a non-private setter, which would be used if constructing an object from outside the class with an object initializer setting the property in question?

    There may be good reasons why initializers are framed as normal property accessors rather than construction parameters, but I think it would be useful to avoid even having to declare a constructor to initialize your read-only autoproperties.

Comment on this article (your first comment on TechieSimon will be moderated)

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s