LA.NET [EN]

Jan 03

Properties are one type of the members you can define in a class. It might seem strange, but a property will only allow us to call a method in a simplified way. In other words, you can see them as sugar for invoking methods (which typically interact with a  private field). Nonetheless, they’re important and most programming languages offer first class support for them (including C# and VB.NET). The CLR allow us to define two types of properties: parameterless and parameterful properties. In this post, we’ll concentrate in parameterless properties (and we’ll leave parameterfull properties for a future post). So, let’s get started…

As you know, most objects have state and that state is saved through instance fields. For instance, if we think about a Student class which has info about the name and address of someone, then we’d probably end up building a class which looks like this:

public class Student {
    public String Name;
    public String Address;
}

And then, you could consume it like this:

var std = new Student();
std.Name = "Luis";
std.Address = "Funchal";
Console.WriteLine( std.Name + "-" +std.Address );

There’s nothing wrong with the previous code. However, there are a couple of observations that might prevent you from using the code as-is:

  • Many argue that exposing fields is not a good idea because it violates one of the tenets of OO programming (data encapsulation).
  • There are times where you might need to validate the values that are being set to a field. Publicly exposing a field means that anyone can set that field to any value and there’s nothing you can do about it.

The solution to this problem is simple: make you fields private and add a couple of methods which allow you to get or set the values of those fields:

public class Student {
    private String _name;
    private String _address;
    public void SetName(String name) {
        //you could perform validation here
        _name = name;
    }
    public String GetName() {
        return _name;
    }
    public void SetAddress(String address) {
        //you could perform validation here
        _address = address;
    }
    public String GetAddress() {
        return _address;
    }
}

And then, you’d need to change the consuming code so that it uses to methods to interact indirectly with the fields:

var std = new Student();
std.SetName( "Luis" );
std.SetAddress( "Funchal" );
Console.WriteLine( std.GetName() + "-" +std.GetAddress() );

This new approach solves the previous problems,but it will also make you write more code and you’ll need to use the new “access” methods for interacting with the fields. Since Microsoft saw these disadvantages as problems,they’ve ended up introducing the concept of (parameterless) property. Here’s a new version of our class that relies in properties:

public class Student {
    private String _name;
    private String _address;
    public String Name {
        get { return _name; }
        set { _name = value; }
    }
    public String Address {
        get { return _address; }
        set { _address = value; }
    }
}

And here are the changes made to the consuming code:

var std = new Student();
std.Name = "Luis";
std.Address = "Funchal";
Console.WriteLine( std.Name + "-" +std.Address );

(Notice that all these snippets end up printing the same results.)

Defining a property is simple: you can specify a get and a set method, which encapsulate the code for reading and setting the value of that property. As you might expect, get and set are both optional (though you do need to define at least a set or a get when defining a new non-abstract property): it all depends on whether you intend to allow read (get) or write (set) access to a specific property. You’ve surely noticed the use of the value parameter from within the set method. This parameter passes the value attributed to the property and, in the previous example, was simply copied into the private backing field of the property.

Even though it’s not mandatory, most properties end up manipulating one or more private fields of the class where they’re defined. When that happens, the property is said to have a backing field. So, adding a property in C# results in adding a pair of (get and set) accessor methods (depends on whether you want to allow read and write access in your property definition) and on adding a property definition to that class’ metadata. The getter and setters introduced in the property text definition are transformed into methods (prefixed with the get_ or set_ word) which are invoked whenever you read or write a value into that property. Notice that the CLR relies only in these methods for accessing the property and performing the “current” operation. Nonetheless, other tools can access the metadata information for getting more information about the members of a specific class.

When we’re creating simple read/write properties like the ones presented in the previous example, then we can reduce the amount of typing by relying in automatic properties. Here’s the revised version of our class that uses this type of properties for introducing the Name and Address properties:

public class Student {
    public String Name { get; set;}
    public String Address { get; set; }
}

Whenever you create a new property and don’t define the body of the get and set methods, the compiler will automatically introduce a backing field and will implement those acessor methods for you. These methods will simply return the value of the backing field (get) or update its value to a new one (set).

Notice that creating an automatic property is not the same thing as adding a field. With properties, the calling code will always be redirected to the get or set method (instead of accessing the field directly). The advantage of using automatic properties is that you can change the implementation of the property in the future (for instance, you might need to add validation to the values passed to the set method) and you won’t have to recompile the consuming code (if it’s in a different assembly).

There are some disadvantages regarding the use of automatic implemented properties. For starters, you cannot initialize an automatic property during its declaration (this means you need to put that initialization code into a constructor). Its use is discourage if you’re performing any serialization/deserialization of that class because you have no control over the name of the backing field and that is what gets serialized. Finally, you should keep in mind that when creating this type of property in C#, you’ll need to define a get and a set method (after all, what would be the use of having an automatic property with only a setter if you have no way to retrieve the value?)

And that’s it for now. Stay tuned for more on properties…

2 comments so far

  1. Jonathan Allen
    5:46 pm - 1-3-2011

    Slight correction. You cannot initialize an automatic property during its declaration IN C#. Visual Basic allows you to write

    Public Property Foo As Integer = 5