Thursday 18 October 2007

Trial software on trial

I'm sure that just like me you often need a bit of software to help you out with a particular task. Last week I wanted something that would help me find album cover art for my MP3 collection; it just makes flipping through music with iTunes a better experience.

A few minutes with Google and I found a likely candidate; after navigating to the parent site I was asked to register my details before downloading the utility. This annoys me! After all, I took the time to find the utility in the first place and registered an interest by wanting to download a trial version. If the software did what I wanted then I would have been more than happy to pay the license fee. If it didn't then no amount of email marketing would have changed my mind. The decision is made in the first few minutes and having to spend a couple of those minutes registering my details (or Mickey Mouse's if I'm feeling particularly mischievous) does not get the vendor off to a good start.

It's a little like walking into a Virgin Megastore and not being able to look around without first filling in an application form - great marketing...for HMV!

So site registration is not my favourite exercise but it registers a poor second to functionally restricted software. Why on Earth would anyone want to provide trial software that is not 100% complete in every way? First impressions count and if my first view of an application leaves me thinking that it could do more then it is highly unlikely that I'll pay good money for it. Knowing that additional features exist in the full version does not sway the argument.

It's a little like taking a new car out for the day on a test drive only to find that the performance has been limited or the air conditioning disabled. It doesn't create a good impression.

So please software vendors, wherever you are. Don't make us register with your site, don't restrict your trial downloads (except by time) and trust your development and design skills to win us over. I, for one, would be a happier shopper and a happy shopper spends more than a disgruntled one.

:-)

Wednesday 17 October 2007

Part 4: Implicit types

With C#2, a variable's type must be explicitly declared, some simple examples are:

int clientAge;
string clientName = "Matthew";
DateTime currentDate = DateTime.Now;

Notice that we do not have to specify a value for the variable at the point at which it is declared, in the example, clientAge will be assigned a value of zero by the compiler. In C#3, variables may be declared with the var keyword in which case the compiler infers the variable type from the value it has been assigned...but it does this at compile time!

So var is not a variant (it's just a keyword that's not named particularly well) and it's not an object type either.

The following constraints apply to the use of the var keyword:

  • var can only be used within a method and not at the class level
  • Any variable created with var must have a value assigned as part of the declaration

Please see the following code for examples:

class VarSamples
{
    //This will not compile, the following error will be reported:
    //The contextual keyword 'var' may only
    //appear within a local variable declaration
    var invalidDeclaration;

    public void ImplicitTypes()
    {
        //The compiler will create postCode as a string variable
        var postCode = "B12 5HP";

        //The compiler will create postCode as an integer variable
        var houseNumber = 8;

        //This will not compile, the following error will be reported
        //Implicitly-typed local variables must be initialized
        var streetName;

        //Perform operations with var variables.
        int nextHouseNumber = houseNumber++;
        string formattedCode = "Postcode: " + postCode;
    }
}

The invalidDeclaration variable will not compile because it has been declared at the class level. This is not allowed for variables declared as var.

The streetName variable will not compile because any variable declared with var must be initialised when it is declared. Otherwise, the compiler is not able to determine an actual type for the variable when it is compiled.

So why do we need var at all?

The var keyword was introduced to support anonymous types that are also a feature of C#3. Anonymous types are described in the next article.

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

 

The newbie guide to C#3, Part 1: Overview

This short series of articles gives you an overview of the new features provided by C#3. The articles are peppered with simple code examples that you can copy directly into a C#3 editor to try them out for yourself. At the end of each article, a link is provided to a standalone class that contains fully commented examples of the features that have been discussed.

The information presented here won't make you a C# guru but they will give you an appetite for the new features that have been added to the language.

Part 2: Automatically implemented properties
Part 3: Initialising objects
Part 4: Implicit types