C#: Why use public readonly fields instead of properties?

The common advice in OOP is to never expose fields publicly, for the simple reason that it allows external code to manipulate the implementation of your class without your class ever knowing about it. You cannot make assumptions about data you do not control.

However, what about readonly fields? They can’t be manipulated and their value never changes, so while they reveal an implementation detail, if that implementation is unlikely to change, or if the type is not visible to much code, then you’re not actually giving up anything important. I find myself writing many small “record”-type classes these days, and I favor the following form:

class MyRecord {
    public readonly T1 Field1;
    public readonly T2 Field2;

Then I ask ReSharper to generate the constructor for me and that’s that. Automatic properties cannot be truly readonly in C# 5, and writing full-blown properties with readonly backing fields is a lot of noise for little benefit. Although C# 6 is set to fix that particular issue, fields have another advantage over properties: they’re always visible in the debugger. For the debugger to show properties, it has to evaluate them, i.e. run code; and for whatever reason it might not be able to. This is when you get the dreaded “Function evaluation timed out” instead of useful information. I get this all the time in the project I’m currently working on.

Finally, while the JIT is reportedly very good at inlining properties when it optimizes, the vast majority of the time, as a developer, you’re running a debug build, and more often than not have a debugger attached to it. This means that using properties everywhere increases the performance delta between your debug and release builds.


Leave a Reply

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

WordPress.com Logo

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

Google photo

You are commenting using your Google 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