Understanding Constructors with C#

I started my IT career as a PHP web developer. It was for an online only travel agent based in the UK. The job was a great learning experience for my first software development job but as there was no senior developer leading the team, looking back our working practises were unbelievably bad. This was due to our lack of experience.
No source control, no development environment and updating the website code directly from the Live server are just some of the atrocities. The experience itself needs an article that I’ll write in the near future, but what does this have to do with Constructors? Well for the 2 years I was at this job, we coded in procedural PHP, not Object Orientation. It wasn’t until after my master’s degree in computer science that I fully understood OOP and the benefit of using constructors.

So, let’s start with a simple explanation of what is a Constructor actually is?

A constructor is simply a way to Construct a class. All classes have a constructor even if you don’t declare one (I’ll explain this later in the article). This still sounds a bit complicated, so let’s look at some code for clarity.

The example I’m using is a “Car” class with properties, and 2 constructors.

public class Car
{
	public string Make { get; set; }
	public string Model { get; set; }

	public Dictionary<string, decimal> OptionalExtras { get; set; }

	/// <summary>
	/// This is the Default Constructor - simply beacuse as it has no parameters
	/// </summary>
	public Car()
	{
		OptionalExtras = new Dictionary<string, decimal>();
	}

	/// <summary>
	/// This is refered to as an overloaded construtor - ie, it takes parameters
	/// </summary>
	/// <param name="make"></param>
	/// <param name="model"></param>
	public Car(string make, string model)
	{
		Make = make;
		Model = model;
	}
}

Ok so we have 2 constructors, the default constructor (zero parameters) and an overloaded constructor (with 2 parameters). Some points to make at this stage. A class can have an unlimited number of constructors or zero constructors, a constructor can take any type or number of parameters. From day to day experience, it’s unusual for a class to have more than 4 constructors unless you are making an API.

So how can we use the Car class?

[TestMethod]
public void TestCarObject()
{
	// a car object constructed by the default construtor
	Car carObj_1 = new Car();

	// a car object constructed by the default construtor
	Car carObj_2 = new Car("Lexus", "GS450h");
	carObj_2.OptionalExtras.Add("Sat Nav", 1500);
}

So far so good? No, We have an issue…

We get this when we try and work with carObj_2 – Object not set to an instance of an object

The property OptionalExtras is of type Dictionary<string, decimal> which requires a new instance. If you look at the default constructor we are “newing” up the instance here, but wea are not doing this on the overloaded constructor. We could copy this code to also be in the overloaded constructor, but this would mean we are repeating code, invalidating the DRY (Don’t Repeat yourself) Principle which is always bad. What we need to do is call the default constructor from the overloaded constructor, here how...

/// <summary>
/// This is refered to as an overloaded construtor - ie, it takes parameters
/// </summary>
/// <param name="make"></param>
/// <param name="model"></param>
public Car(string make, string model) :this()
{
	Make = make;
	Model = model;
}

Ok cool. Let’s update the class to add some more properties and add in a new constructor. This 3rd constructor will call the 2nd and in turn that will call the default. I have updated the class to have a new Boolean for IsHybrid and an int for EngineSizeCC as 2 new properties. let’s have a look at the code.

public class Car
{
	public string Make { get; set; }
	public string Model { get; set; }

	public bool IsHybrid { get; set; }
	public int EngineSizeCC { get; set; }

	public Dictionary<string, decimal> OptionalExtras { get; set; }

	/// <summary>
	/// This is the Default Constructor - simply beacuse as it has no parameters
	/// </summary>
	public Car()
	{
		OptionalExtras = new Dictionary<string, decimal>();
	}

	/// <summary>
	/// This is refered to as an overloaded construtor - ie, it takes parameters
	/// </summary>
	/// <param name="make"></param>
	/// <param name="model"></param>
	public Car(string make, string model) : this()
	{
		Make = make;
		Model = model;
	}

	/// <summary>
	/// This is refered to as an overloaded construtor - ie, it takes parameters
	/// </summary>
	/// <param name="make"></param>
	/// <param name="model"></param>
	public Car(string make, string model, bool hybrid, int enginesize) : this(make, model)
	{
		IsHybrid = hybrid;
		EngineSizeCC = enginesize;
	}
}

Let’s have a look at how we call the new constructor.

[TestMethod]
public void TestCarObject()
{
	// a car object constructed by the default construtor
	Car carObj_1 = new Car();

	// a car object constructed by the overloaded construtor 1
	Car carObj_2 = new Car("Lexus", "GS450h");
	carObj_2.OptionalExtras.Add("Sat Nav", 1500);

	// a car object constructed by the overloaded construtor 2
	Car carObj_3 = new Car("Lexus", "LS600h", true, 5000);
	carObj_3.OptionalExtras.Add("Sat Nav", 1500);
	carObj_3.OptionalExtras.Add("Cruise Control", 250);
}

So, there we have it, a simple explanation of how to effectively and easily use constructors with your classes in C#. By being clever with constructors we can ensure our code is kept minimal and easy to debug/maintain. If you have Visual studio, try debugging through the constructor calls using this code and you will see how it jumps back to the previous constructors. Fun Times! smile


JGilmartin Profile Image

JGilmartin

Technical Architect at Pinewood Technologies

Rating: 2890

C# Expert

Offline


Tutorial Statistics
  • Views: 338
  • Comments: 0
  • Author: JGilmartin (2890)
  • Date: 26/11/2016 14:04
Tags
C#

© 2016 - 2018 - IntermittentBug