Constructors
In the first lesson of the theme a house was built empty, and its fields were filled in later, line by line. Forget one line, and the program gets a house with no floors:
var a = new House();
a.Color = "red";
a.Floors = 2;
var b = new House();
b.Color = "blue";
Console.WriteLine(b.Color + ", " + b.Floors); // blue, 0
class House
{
public string Color = "";
public int Floors;
}The line b.Floors = 1; was skipped, so b.Floors stayed 0. The compiler does not object: to it, zero floors is an ordinary number.
Real houses don't work like that. The builders get an order form right away, "a red house, two floors", and hand the house over finished. In C# such an order form is a constructor.
What a constructor is
A constructor is a special method of a class that runs when an object is created with new. It receives the starting values and puts them into the fields:
var a = new House("red", 2);
Console.WriteLine(a.Color + ", " + a.Floors); // red, 2
class House
{
public string Color;
public int Floors;
public House(string color, int floors)
{
Color = color;
Floors = floors;
}
}Let's go through the constructor and its call:
- Its name is the name of the class:
House. - It has no result type, not even
void: a constructor returns nothing, it fills in the new object. new House("red", 2)creates an object and immediately calls the constructor with the arguments"red"and2.- The body puts the parameters' values into the fields, and
agets a house with everything filled in.
Now the floors cannot be forgotten: the call new House("red") without a second argument does not compile. The string field Color no longer needs = "". The constructor puts a string into it anyway, so there is no CS8618 warning.
A constructor with a single statement can be written with =>, like a method: public House(string color) => Color = color;.
The default constructor
In the first lesson of the theme House had no constructor, yet new House() still worked. If a class has no constructor at all, the compiler adds a default constructor: no parameters and an empty body. The fields then get the starting values from their declarations or their default values.
As soon as you write your own constructor, the default constructor is gone. The compiler assumes you have decided yourself how an object is built. Interviewers often ask: "When does a class have a parameterless constructor?" The answer: when the class has no constructor of its own, or when a parameterless constructor is declared explicitly.
Overloading constructors
Here the order form and the constructor differ. A building firm has one order form, but a class can have several constructors, as long as their parameter lists differ:
var a = new House("red");
var b = new House("blue", 3);
Console.WriteLine(a.Floors + " " + b.Floors); // 1 3
class House
{
public string Color;
public int Floors;
public House(string color) : this(color, 1) { }
public House(string color, int floors)
{
Color = color;
Floors = floors;
}
}Several methods with one name and different parameters are called overloading. The compiler picks the right version by the arguments of the call:
new House("red")has one string argument, soHouse(string color)is called;new House("blue", 3)has a string and a number, soHouse(string color, int floors)is called.
Ordinary methods of a class are overloaded the same way. Console.WriteLine has 20 overloads: for int, for string, for bool and for other types. Overloads must differ in the number or the types of their parameters. Two methods that differ only in their result type do not compile (CS0111).
Methods declared among the top-level statements cannot be overloaded. A second method with the same name there gives error CS0128, which is why overloading is shown on methods of a class.
Calling through this(…)
The : this(color, 1) after the parameters means: first run another constructor of this class with these arguments. The short constructor does not repeat the assignments; it hands the work to the full one and supplies one floor.
Let's go through the call new House("red"):
- The constructor with one parameter is chosen, and
coloris"red". : this(color, 1)calls the full constructor with the arguments"red"and1.- The full constructor fills in
ColorandFloors. - The body of the short constructor runs. It is empty:
{ }.
If a check of the floors is needed later, it is written in one place, the full constructor.
Common mistake
You wrote your own constructor, but still create the object without arguments, as before:
var a = new House(); // ✗
Console.WriteLine(a.Floors);
class House
{
public int Floors;
public House(int floors)
{
Floors = floors;
}
}error CS7036: There is no argument given that corresponds to the required parameter 'floors' of 'House.House(int)'The program does not compile. The default constructor is gone, and the only constructor requires the argument floors. Pass it: new House(2). Or declare a parameterless constructor yourself: public House() : this(1) { }.
Key points
- A constructor is named after the class, has no result type and runs on every
new. - If a class has no constructors of its own, the compiler adds a default constructor; your own constructor removes it.
- Overloading means several methods or constructors with one name and different parameters; the version is chosen by the arguments.
: this(…)calls another constructor of the same class so the code is not repeated.