Tuesday, August 30, 2011

Properties or Fields?

There was a great conversation on Twitter today about properties and fields. The discussion was about whether it makes sense to expose variables as fields and not bother with the overhead of properties. After all, it's quick and easy and you can always change it later, right? One participant suggested there could be design "assumptions / deficiencies / violations / smells" from using properties instead of fields, and someone else pointed out that the intermediate language, or IL, for properties is larger and will take more nanoseconds to process.

So what's the word?

First, I'll make a call to action for you to use the comments section below because I'm curious if anyone has ever had an issue with an application because their properties were too slow. I'm not talking about a property that fires some exotic validation routine that performs asynchronous server operations and crunches numbers approaching infinity before completing. I'm talking a simple property with a backing field and possibly a property change notification. It's highly unlikely the few extra IL codes or nanoseconds spent ever presented any tangible problems just because the implementation was a property and not a field.

So what does the property buy us?

First, it's important to note that just because a property looks like a field to the outside world doesn't mean that it is interchangeable. Changing a field to a property is a breaking change and requires all of your code to be recompiled. That's an expensive operation, and one that should immediately call out to the advantage of using a property from the start. Even though the language allows properties and fields to appear the same, the underlying IL is different. Consider the code to access a field:

ldfld string [MyExample]MyExample.MyClass::SomeVariable
Compared to the code to access the same "field" when it is exposed as a property:
callvirt instance string [MyExample]MyExample.MyClass::get_SomeVariable()

As you can see, the property provides the language convenience of looking like a field but underneath is still a method.

Personally, I believe the best description of the benefits of properties is in Jeffrey Richter's CLR via C#. Chapter 10 covers properties. I obviously don't want to reveal too much because every serious developer should have this book in their library, but I'll summarize a few key points:

  • It's easy to corrupt a field because there is no validation whatsoever (Jeffrey gives the example of assigning a negative age)
  • Properties provide data encapsulation
  • Properties have the benefit of allowing data to be validated and cleansed, and can throw exceptions when something is wrong
  • Properties can perform other actions such as interacting with a cache or triggering a notification
  • Properties can participate in data-binding, fields cannot

Jeffrey's book goes on to make several very insightful comparisons between properties and fields to help you determine the pros and cons for your particular situation. The bottom line is that good design choices are seldom related to reducing the number of keystrokes to complete a class. There are many factors involved and while it is a bit more code to expose a public property, I tend to follow Jeffrey's strong suggestion that all fields should be private, and access to them restricted through methods. Properties have the dual advantage of being special-purpose methods that can perform several tasks when obtaining or presenting a value, while presenting themselves with an interface that looks like a simple field.

Jeremy Likness