sharp bites

standing on the shoulders of giants

Public fields vs. Public properties

ScottGu blogged some time ago, among other interesting things, about the difference between public fields and public properties.

I had always seen comments about the convenience of using public properties instead of public fields, but I hadn’t seen a real explanation until now. I tought, “why should I bother writing a getter and a setter? If I just use a public Foo field, I can refactor it into a Property if it turns out I have to.” It seems I wan’t the only one that thought this very same thing.

But it turns out there are some differences:
  • You can’t databind against a variable.
  • Changing a variable to a property is a breaking change. When you change a field to a property you need to re-build all code that used that field.
  • Reflection works differently on variables vs. properties, so if you rely on reflection, it’s easier to use all properties.
There are some other relevant points in both posts.
From Jeff’s:
  • Distinguishing public and private using only case is an accident waiting to happen. I still don’t have a clear view if I should be using _bar = bar or = bar.
  • Is it a property or a method? A property should do less work– a lot less work– than a method. Properties should be lightweight. If your property incurs significant effort, it should be refactored into an explicit method.
From Scott’s, there is some syntactic sugar for C#3 (or is it 3.5?):

Automatic Properties
This cleans up our classes from all the innecesary private fields.
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }

Object initializers
Allow you to atomically initialize an object lacking an appropiate constructor. More on this.
Person person = new Person { FirstName="Scott", LastName="Guthrie", Age=32 };
Collection initializers
Same annonymous methods, but applied to collections.
   List people = new List {
new Person { FirstName = "Scott", LastName = "Guthrie", Age = 32 },
new Person { FirstName = "Bill", LastName = "Gates", Age = 50 },
new Person { FirstName = "Susanne", LastName = "Guthrie", Age = 32 }