Showing posts with label Automatic properties. Show all posts
Showing posts with label Automatic properties. Show all posts

Wednesday, 17 October 2007

Part 3: Initialising objects

Consider the following simple class definition:

//Simple client class used to demonstate
//C#3 object initialisation
class Client
{
    //Read-write property for the client's name
    public string Name { get; set; }

    //Read-write property for the client's age
    public int Age { get; set; }

    //Read-write property for the client's height
    public double Height { get; set; }

    //Read only property that is True for existing
    //clients and False for new clients
    public bool IsCurrent { get; private set; }
}

A constructor has not been explicitly created for this class so the compiler will generate a default, parameterless one for us. This means that an object can be created and properties assigned inthe way that we are currently used to with C#2

//Create a client object using the default constructor
Client firstClient = new Client();

//Assign values to the class properties that have public set methods
firstClient.Name = "David";
firstClient.Age = 32;
firstClient.Height = 124;

However, with C#3, we are now able to create an object using any of the following methods:

//Construct the object by supplying the client Name
Client secondClient =
    new Client { Name = "Matthew" };

//Construct the object by supplying
//the client Name & Age
Client thirdClient = 
    new Client { Name = "Sarah", Age = 21 };

//Construct the object by supplying
//the client Name & Height
Client fourthClient =
    new Client { Name = "Daniel", Height = 131 };

//Construct the object by supplying
//the client Height only
Client fifthClient = new Client { Height = 108 };

This is essentially identical to creating a client object with the default constructor and then calling each property set method as appropriate. Looking at the disassembled code shows us what isactually happening for these client objects.

Client <>g__initLocal0 = new Client();
<>g__initLocal0.Name = "Matthew";
Client secondClient = <>g__initLocal0;

Client <>g__initLocal1 = new Client();
<>g__initLocal1.Name = "Sarah";
<>g__initLocal1.Age = 0x15;
Client thirdClient =<>g__initLocal1;

Client <>g__initLocal2 = new Client();
<>g__initLocal2.Name = "Daniel";
<>g__initLocal2.Height = 131.0;
Client fourthClient = <>g__initLocal2;

Client <>g__initLocal3 = new Client();
<>g__initLocal3.Height = 108.0;
Client fifthClient = <>g__initLocal3;

As the code above shows, each client is constructed using the default constructor and then the property set methods are called as necessary. Of course, we cannot specify a value for IsCurrent when creating a client object because the set property is marked private (as shown in the first code snippet). Trying to do so will generate a compile time error of something like: The property orindexer ‘Blog.Client.IsCurrent’ cannot be used in this context because the set accessor is inaccessible.

Part 4: Implicit types

Part 2: Automatically implemented properties

C#2 provides the ability to create properties that encapsulate class member variables; the following code provides a simple example:

//Private member variable to store the client name
private string name;

//Read-write property for the client?s name
public string Name
{
    get
    {
        return name;
    }
    set
    {
        name = value;
    }

The idea here is that the property prevents the class variable from being accessed directly. A property can be made read only as follows; this is simply a property that does not have a set statement.

// Read only property that returns the client?s name
public string Name
{
    get
    {
        return name;
    }

C#3 provides a shortcut syntax for creating class variables and associated properties; the first code example can be shortened to:

// Shortcut syntax for creating properties
//and underlying member variables
public string Name { get; set; } 

And of course, the principle of read only (or write only for that matter) properties is also supported using this new syntax:

// Shortcut syntax for creating properties and underlying
//member variables (this time ClientName is read-only)
public string Name { get; private set; }

For this shortened syntax, the compiler actually generates all of the required code behind the scenes. So in effect, you end up with exactly the same code that you would have got if you had written it using the available syntax of C#2. The code below shows the MSIL that is generated from the source code; note the use of the [CompilerGenerated] attribute that decorates the code.

[CompilerGenerated]
private string k__BackingField;

public string Name
{
     [CompilerGenerated]
     get
     {
         return this.k__BackingField;
     }
    [CompilerGenerated]
    set
    {
        this.k__BackingField = value;
    }
}

Automatically implemented properties provide a way to quickly expose class member variables; we will examine this feature more in the next article.

Part 3: Initialising objects