Expression Bodied vs. Auto Read-Only Properties

C#6 brought some nice short-hand ways of handling properties. I really like them, because they take away much boilerplate code. But as with all new tools, it’s easy to use them wrongly until they are familiar.

These are two attempts to declare a readonly property that preserves the time stamp of when the object was created. They look similar, but only one of them is right.

class SomeClass
{
  public DateTime CreationTimeA => DateTime.UtcNow;
  public DateTime CreationTimeB { get; } = DateTime.UtcNow;
}

The difference is that the first one is an expression bodied member – a function that executes every time the getter is executed, while the second is a read-only auto property that is initiated once when the object is created. It is of course the latter behaviour we want for a creation time stamp. A small test program shows the difference.

  var s = new SomeClass();
  Console.WriteLine($"A: {s.CreationTimeA.Ticks}, B: {s.CreationTimeB.Ticks}");
  Thread.Sleep(100);
  Console.WriteLine($"A: {s.CreationTimeA.Ticks}, B: {s.CreationTimeB.Ticks}");

The output shows how A is changed after the sleep, while B keeps the creation timestamp.

A: 636435047872825754, B: 636435047872825754
A: 636435047873833584, B: 636435047872825754

If we expand the short-hand code into familiar old-school C#, the difference is made clear.

class SomeClass
{
  public DateTime CreationTimeA
  {
    get
    {
      return DateTime.UtcNow;
    }
  }
 
  private DateTime creationTimeB;
 
  public SomeClass()
  {
    creationTimeB = DateTime.UtcNow;
  }
 
  public DateTime CreationTimeB
  {
    get
    {
      return creationTimeB;
    }
  }
}

While I do like the new short-hand syntax, it certainly has drawbacks such as this subtle(?) difference that can introduce nasty bugs. Syntax features that make the language more efficient for experienced developers also make the language harder to learn for beginners.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.