Why constructors exist
Without a constructor, you set up an object after creating it, one field at a time:
Dog dog = new Dog();
dog.name = "Rex";
dog.age = 4;
That takes three lines for one usable dog, and nothing forces you to do it. If you forget a line, you end up with a half-initialized object. A constructor solves both problems. It is a special method that runs automatically when you write new, and it receives the values the object needs.
Defining a constructor
A constructor has two distinguishing features:
- Its name is exactly the class name.
- It has no return type, not even
void.
class Dog {
public string name;
public int age;
public Dog(string name, int age) {
this.name = name;
this.age = age;
}
}
It is marked public so that code outside the class can use new Dog(...). A constructor that is not public can only be used from inside the class.
The this keyword
The parameter name and the field name have the same identifier. Inside the constructor, a bare name refers to the parameter, because the closest declaration wins. The keyword this means "the object being worked on", so this.name is the field and plain name is the parameter. The assignment this.name = name; therefore copies the argument into the object.
Leaving out this is a classic mistake:
public Dog(string name, int age) {
name = name; // assigns the parameter to itself
this.age = age;
}
This compiles, but the compiler warns that an assignment was made to the same variable. The field name is never set, so it keeps its default value, null. When you print it with string concatenation, you get an empty piece of text where the name should be. If the parameter had a different name, such as n, then this. wouldn't be needed.
Calling the constructor
Pass the arguments in the same order as the parameters:
Dog rex = new Dog("Rex", 4);
Dog luna = new Dog("Luna", 7);
When these lines finish, rex.name is already "Rex" and rex.age is 4. The same holds for Luna.
The default constructor and overloads
If you write no constructor at all, C# provides a hidden one with no parameters and an empty body. That is why new Dog() worked in earlier lessons. As soon as you declare any constructor of your own, the hidden one disappears. After that, new Dog() is a compile error, because no constructor matches the call. The error mentions a missing argument for the parameter name.
A class may have several constructors with different parameter lists. This is called overloading. One constructor can reuse another with : this(...):
class Dog {
public string name;
public int age;
public Dog() : this("Unknown", 0) { }
public Dog(string name, int age) {
this.name = name;
this.age = age;
}
}
Now new Dog() produces a dog named "Unknown" with age 0, and new Dog("Rex", 4) still works.
Common mistakes
- Adding a return type.
public void Dog(...)is no longer a constructor. C# rejects it, because a member can't have the same name as its class. - Misspelling the class name. A constructor's name must match the class exactly, including case.
- Wrong argument order.
new Dog(4, "Rex")doesn't compile, because the types don't match the parameters. - Forgetting
public. Without it, the constructor is private andnew Dog(...)from another class is rejected. - Calling
new Dog()after adding a constructor with parameters. Supply the arguments, or add a parameterless constructor.
The exercise, step by step
The Dog class already declares the fields name and age. The expected output is two lines:
Rex is 4
Luna is 7
- Add the constructor below the fields:
public Dog(string name, int age). Inside it, assignthis.name = name;andthis.age = age;, so every dog is fully set up the moment it is created. - Create the two dogs in
MainFunction:rexfrom"Rex"and4,lunafrom"Luna"and7. The existingConsole.WriteLinelines then print each dog's name and age.
class Dog {
public string name;
public int age;
public Dog(string name, int age) {
this.name = name;
this.age = age;
}
}
class Solution {
public void MainFunction() {
Dog rex = new Dog("Rex", 4);
Dog luna = new Dog("Luna", 7);
Console.WriteLine(rex.name + " is " + rex.age);
Console.WriteLine(luna.name + " is " + luna.age);
}
}
Key takeaways
- A constructor has the class's name, no return type, and runs when you write
new. - Use
this.field = parameter;when a parameter has the same name as a field. - Declaring any constructor removes the hidden parameterless one.
- Overloaded constructors can share work with
: this(...).