P3.NET

Demystifying Auto Properties

There seems to be a lot of confusion going around about auto properties in C# and, starting with Visual Studio 2010, VB. Quite a few people are erroneously comparing them to fields and then trying to compare the two approaches. This is just plain wrong. This article attempts to clarify exactly what auto properties are and when they are useful. Before diving into auto properties it is important to differentiate between properties and fields and when to use each.

Fields

A field is a type member that holds a value. Every field has a type.  A field can be read or written. There is not any way to limit code to read or write access. The best that can be done is limit the field using the standard accessibility (public, protected/family, internal). A field simply stores a value so any (legal) value can be stored (if it gets past the compiler).

Fields, because they do little, are very fast to access and use. Fields execute no code when they are accessed so there is no worries about custom code being executed. All in all fields are low level. Because fields are so low level they can do almost nothing other than store a value. If a value is type-compatible with a field then it can be stored there irrelevant of any business rules or assumptions that might be desired. The following code demonstrates a few simple fields.

class Employee
{
   public int Id;

   public bool IsFullTime;
   public EmployeeType Status;

   public string FirstName;
   public string LastName;
}

 

Properties

A property is a type member that looks like a field but acts like a method. Every property has a type just like a field.  A property stores no data on its own. In fact a property is actually just a set of two methods: a getter and a setter. These accessors are used to get or set the value of a property. The getter has no parameters and returns the same type as the property.  The setter accepts a single parameter (usually) of the property’s type and returns nothing.

Most properties have both accessors but some have only a getter and, rarely, a setter. A property with only a getter cannot be assigned a value whereas a property without a getter can not be retrieved.

Properties are generally one of two types: a field wrapper or a computed field. A field wrapper property has a field that backs the property value, known as the backing field. Field wrappers are commonly used to add validation to field assignments. A computed field property generally only has a getter and returns a calculated value. The calculated value is often based upon some underlying field values but not always.  The following demonstrates a class with some properties.

class Employee
{
   public int Id 
   {
      get { return m_id; }
      set { m_id = value; }
   }

   public bool IsFullTime
   {
      get { return m_type == EmployeeType.Full; }
   }

   public EmployeeType Status
   {
      get { return m_status; }
      set { m_status = value; }
   }

   public string FirstName rstName
   {
      get { return m_firstName ?? “”; }
      set { m_firstName = value; }
   }

   public string LastName astName
   {
      get { return m_lastName ?? “”; }
      set { m_lastName = value; }
   }

   private int m_id; p;m_id;
   private EmployeeType m_status;

   private string m_firstName;
   private string m_lastName;
}    

In the above code most of the properties are wrapper properties.  IsFullTime is a computed property.  Notice that most wrapper properties simply get or set a backing field value.  This is pretty typical code.

Properties vs Fields

One of the big areas of debate is when to use properties and when to use fields.  Properties provide two very powerful features: field-like access and accessors.  A property is accessed just like a field.  In the following code can you identify which value is the field and which is the property?

Thread.CurrentThread.Join(Timeout.Infinite);

CurrentThread is a property of Thread while Infinite is a field of Timeout.  Yet they both look and behave like fields.  The CurrentThread getter is used to get the current thread from the Thread class.  The Infinite field is used to determine how long to wait.  This makes it real easy to use properties.  Note however that the underlying generated code is not the same for properties and fields.  For fields the underlying value is read or written directly.  But for properties a call to the getter or setter is inserted into the code.  Hence properties can be, theoretically, slower.

Because the property accessors are used to access the property you can execute arbitrary code whenever a propery is read or written.  This allows for things like validation, redirection or logging.  In the code given earlier the FirstName and LastName properties ensured that the string properties always returned a non-null value (a guideline that should be followed).  If a field would have been used instead then the caller would have had to handle the case of a null value.

The general guideline is to use public properties to expose private fields.  Even if the property simply returns the field the benefits outway the disadvantages.  For one if, at a later date, validation or some other code needs to be executed when accessing the field (or if the field is removed altogether) then a property accessor can be modified without breaking compatibility with existing code.  If a field is used then it is a breaking change to convert code from using a field to using a property.  In other words all the existing code would have to be recompiled before the “new” property would be used.

Public fields are not all bad.  Actually they are except for the very special case of read only fields.  It is generally OK to expose a public field if the field is read only (or constant) and is unlikely to change.  In all other cases expose a property instead.  Protected fields should generally be avoided as well.  Create a private field and expose a protected property.  Remember that a protected member is still public to derived types so it should follow the same rules as public members.

Where the debate often comes in is the performance.  Many people will point out that fields are faster than properties and this is technically true.  But the JIT can optimize property calls to all but eliminate the actual accessor call so the actual runtime performance will be negliable in almost all cases.  In general the 80/20 rule of performance tuning will eliminate any need to use public fields to avoid property performance issues.  Given the advantages of properties and their seamless integration into code there really is no good reason not to use them.

Auto Properties

The only real disadvantage of properties is all the code you have to write.  For just a simple wrapper you have to write the property declaration, the two accessors and the backing field.  Even worse is that the getter generally just returns the field while the setter just sets it.  This is ideally suited for code generators since it is boiler plate code.  In fact there are code snippets to do just that.

But if it is so easy to generate then why can’t the compiler just do it for us?  Well, as of VS 2008, it can.  Enter auto properties.  An auto property is nothing more than a wrapper property and its backing field.  The difference is that it can be defined in a single line of code.  Here is the Employee class using auto properties.

class Employee
{
    public int Id { getset; }

    public bool IsFullTime
    {
        get { return Status == EmployeeType.Full; }
    }

    public EmployeeType Status { getset; }

    public string FirstName
    {
        get { return m_firstName ?? “”; }
        set { m_firstName = value; }
    }

    public string LastName
    {
        get { return m_lastName ?? “”; }
        set { m_lastName = value; }
    }
            
    private string m_firstName;
    private string m_lastName;
}    

The Id and Status properties have been converted to auto properties.  Notice the backing fields were removed and the bodies of the accessors have been as well.  In this case the properties allow get and set operations but either keyword can be removed to make the property read-only or set-only.  The big advantage here is less code to read and write.  The name properties cannot be converted to auto properties because they do more than get or set the backing field.  Furthermore the IsFullTime property remains unchanged because it is a computed property and had no backing field anyway.

What’s going on behind the scenes here?  It is actually pretty straightforward.  When the compiler sees an auto property it generates a private backing field for the property.  Then the compiler generates the accessor(s) to get or set the backing field.  Basically all that boilerplate code is generated for you.  So whenever you need a property without any custom accessor code, use an auto property to save yourself some typing.

One of the questions often asked in the forums is why someone should use a field over an auto property.  The answer is that you should use a property over a field in almost all cases.  Whether that property is a normal property or auto property is not relevant.  An auto property just means that the compiler generates the property definition for you.  There is absolutely no other differences.  None.  Nadda.

Compatibility

Great new feature, but what if you are stuck on .NET v2?  Well here is the good news – the compiler generates all the code.  The VS 2008 compiler for C# (and VS 2010 for VB) generate all the code during compilation.  There is no runtime support needed.  Therefore the version of .NET you are using (other than v1.x) does not matter.  In fact there is no real way of distinguishing between auto properties and normal properties at runtime.  The best you can do is dump the code and look at the field name to see if it matches something the compiler might generate.  The point is that you can use this feature on any version of .NET provided you are using at least the VS 2008/2010 version of the C#/VB compiler. 

So, in summary, use an auto property whenever you have a wrapper property with no custom accessor code.  Use public properties (normal or auto) in lieu of public fields in every case except for readonly fields which may be exposed publicly.  Do not worry about the performance differences unless your performance tuning determines that the properties are truly slowing down your application.

Comments

  1. You state that “The answer is that you should use a field over a property in almost all cases”.

    I was under the impression that it would be the other way around, use a property over a field in almost all cases.

    Cheers,

  2. MichaelTaylor

    You are correct. That was a typing error on my part. I have fixed the post. Thanks.