C# Class Types

This post is based on Chapter 5 of Andrew Troelsen’s “Pro C# 2008 and the .Net Platform” availble from Apress.

Constructors and Constructor Chaining

Quick note on constructors, don’t think I ever realised this, but of course every class has a default empty constructor that you don’t have to define. However, you know how you then sometimes get the “[method] does not contain a constructor that takes ‘0’ arguments” – well as soon as you define any constructors – you loose the empty default, and you will then have to explicitly define this. I guess the reasoning is that you (the dev) are now in charge of defining constructors.
Also note that it’s generally best practise  to leave the default constructor empty as really all you want is an ability to define an empty object with all vaues as default. It’s by no means a requirement, but just a general rule of thumb.

Constructor Chaining is the black art of using the this keyword to forward constructor parameters. The general idea is to avoid code redundancy by maintaining all constructor logic in one detailed constructor, basically one that takes all possible parameters. All other less specific constructors will then forward their supplied values along with some default or even null values for the “missing” parameters – and example:

public TestClass() {} //empty default
public TestClass(string strValue) : this (strValue, 0) { /* forward string value to master constructor */ }
public TestClass(int intValue) : this (String.Empty, intValue) { /* forward int value to master constructor */ }
public TestClass(string strValue, int intValue) { /* master constructor, handle all init logic */ }

So this, when done properly, gives us a nice clean way of initialising our objects while maintaining this logic in one (and only one) place.
Note that the work-flow in the above is that the master constructor (this is not a real term, it’s just what we are calling the most detailed constructor) will execute first, and once this returns the initially called constructor will execute. So it would be possible to perform some logic here, but not particularly advisable, seeing as the overall purpose of the pattern is to centralise all init code – but then again, you could see this as another bit of flexibility provided by this approach.

The static Keyword: Static Members, Constructors and Classes

Right, so the key thing to realise here is that static members operate on the class level as opposed to the object level.
I think I was for a long time a bit confused about when to use the static keyword, and generally I would kind of use this quite inconsistently whenever I thought it was too much bother to have to create an object… and really that’s not far off the mark. Basically if you ever find yourself creating an object with the sole purpose of executing one specific method, you probably have a good candidate for a static method.
Quite often static methods are used in utility classes – for example look at the static methods of String and Array.

So, of course static methods can only operate on static data and can only call other static methods. What is more interesting about static methods is the way their scope allows you to set certain data once across all existing and subsequently created objects of this class.
So a possible example is an Order object with a static VAT property (that’s sales tax if you’re not English) – you can set this static property once, and the value will be present for all subsequent objects created. Likewise if you modify the static property this will affect all existing and subsequently created objects.

One closely related and very useful feature is the static constructor, which is a somewhat different beast to your normal constructor. Like static members this operates on a class level, and so it is invoked by the runtime before any object level constructors, either the very first time an object of this class (type) is created or the first time a static member of this class  is accessed.

So what would you use that for? Well, maybe you have some global property, like indeed a VAT rate, that is only to be loaded in once for all objects, and if modified should be modified across all existing and subsequent objects. Note that you can only have one static constructor per class, and that this does not have any access modifiers and does not take any parameters, e.g:

static TestClass() { /*Do some class level init here */ }

A missing piece for me in all this is object life time, and how often these static class level constructors would be called – I am assuming for now that we are looking at application life time here, but I will update this post when I find out (soon).

Static classes is the last static bit to consider. Basically these cannot be instantiated with the new keyword, and all members and fields must be defined as  static.
I guess you would use this for utility classes and anything that you never want the user to instantiate (don’t confuse this with abstract classes though, these are intended to serve as the basis for inheritance hierarchies and represent objects that are too general to be instantiated, e.g. Vehicle, Animal or Employee).
A fairly well known example of a static method is the Program class in console applications – this makes sense here as you don’t want people to create Program objects.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: