Pages

Monday, 16 August 2010

Immutable, Auto-Implemented Properties in C#

Over the past few months I've been getting a lot more into immutability. If you want to know why you should be using immutable types start with this blog post by Bertrand Le Roy.

Until recently I, like most other developers had been creating my properties like this...

public class Person
{
  public DateTime BirthDate { get; private set; }

  public string FavouriteSong { get; set;}

  public Person(DateTime birthDate)
  {
    BirthDate = birthDate;
  }
}

Pretty straight forward - the BirthDate is required and must be set during construction of the object whilst the FavouriteSong is optional. The other reason for writing properties this way is simplicity and code succinctness. It also allows more 'interesting' properties to be more easily identified. For instance, this new Age property stands out from the other two and 'asks' to be unit tested.

public class Person
{
  public DateTime BirthDate { get; private set; }

  public string FavouriteSong { get; set;}

  public int Age
  {
    get
    {
      var now = DateTime.Today;
      var age = now.Year - bday.Year;

      if (bday > now.AddYears(-age))
        age--;    

      return age;
    }
  }

  public Person(DateTime birthDate)
  {
    BirthDate = birthDate;
  }
}

I should, however, be making the BirthDate property immutable - it isn't gonna change! This does make the code less neat though...

public class Person
{
  private readonly DateTime _birthDate;
  public DateTime BirthDate { get { return _birthDate; } }

  public string FavouriteSong { get; set;}

  public int Age
  {
    get
    {
      var now = DateTime.Today;
      var age = now.Year - bday.Year;

      if (bday > now.AddYears(-age))
        age--;    

      return age;
    }
  }

  public Person(DateTime birthDate)
  {
    _birthDate = birthDate;
  }
}

Auto-implemented properties are a .Net construct and are used as a template, at design-time, to create a 'real' pair of _get _set methods. So, what I'd like to be able to do is this ...

public class Person
{
  public DateTime BirthDate { get; private readonly set; }

  public Person(DateTime birthDate)
  {
    _birthDate = birthDate;
  }
}

Anyone from Microsoft like to chime in?

No comments:

Post a Comment