1. Simple Constructors
Constructor — is a special method of a class that gets called automatically when you create an object. It initializes (sets up) the object: sets initial values, does checks, and can even cheer you up if you write a joke in it.
A constructor lets you create an object in a certain state right away, instead of setting all its data separately through fields and properties by hand. It's convenient and safe, because you specify all the important parameters right away — and you won't forget anything critical.
Without a constructor, your code can look bulky and be prone to mistakes:
Person p = new Person();
p.Name = "Yulya";
p.Age = 25; // What if we forget to set the age?
With a constructor:
Person p = new Person("Yulya", 25); // Everything is passed right away and the object is ready to roll!
Constructor Syntax
A constructor is a special "method" whose name matches the class name exactly and which doesn't have a return value (not even void). Here's what a default constructor looks like:
public class Person
{
// Default constructor (no parameters)
public Person()
{
// You can write initialization code here
}
}
The default constructor is like an invisible "helper" that doesn't take any parameters and just initializes all the fields and properties of your class with their default values:
- For numeric types (int, double, float, etc.) it'll be 0.
- For boolean type (bool) it's false.
- For reference types (string, other classes) it's null (which means "nothing", "no reference to an object").
- For DateTime it'll be 01.01.0001 00:00:00.
How do you call a constructor?
Basically, when you write the new operator to create an object, you're calling the constructor!
Person p = new Person();
If you don't explicitly define any constructor, the C# compiler will create a default constructor (no parameters) for you. But if you declare at least one of your own — the default constructor disappears, and the compiler will ask you to be honest and add it manually if you need it.
Example
Let's add a constructor to our app's class. Here's a simple version of a student class:
public class Student
{
public string Name;
public int Age;
// Constructor with two parameters (name and age)
public Student(string name, int age)
{
Name = name; // Assign value to the field
Age = age;
}
}
Now you can create a student like this:
Student s = new Student("Ivan", 21);
Console.WriteLine($"{s.Name}: {s.Age} years"); // Ivan: 21 years
- We declared the constructor with the same visibility (public) as the class itself.
- In the constructor, we assign values to the fields using the passed parameters.
- This approach protects you from forgetfulness: the compiler will make you specify name and age when creating an object.
2. Constructor Parameters
In C#, you can declare several constructors with different sets of parameters. This is called constructor overloading (we'll talk about method overloading later).
For example, let's add a constructor with no parameters:
public class Student
{
public string Name;
public int Age;
// Default constructor
public Student()
{
Name = "Nameless";
Age = 0;
}
// Constructor with parameters
public Student(string name, int age)
{
Name = name;
Age = age;
}
}
Now both options are possible:
Student s1 = new Student(); // Name: Nameless, age: 0
Student s2 = new Student("Olya", 22); // Name: Olya, age: 22
Using a constructor for validation
A constructor is a great place to check the "quality" of incoming data. For example, a student can't have a negative age!
public Student(string name, int age)
{
if (age < 0)
throw new ArgumentException("Age can't be negative!");
Name = name;
Age = age;
}
Now if someone tries to create a student Student("Malysh", -2), the app will throw an exception (ArgumentException). This approach is often used for "rock-solid" data reliability.
3. Initializing Complex Objects
Often in real apps, one object can be "built" not just from primitives, but also contain other objects:
public class Group
{
public string GroupName;
public Student[] Students;
public Group(string groupName, Student[] students)
{
GroupName = groupName;
Students = students;
}
}
Now you can easily create a group with a set of students:
var students = new Student[]
{
new Student("Ivan", 20),
new Student("Maria", 19)
};
Group g = new Group("Group-101", students);
Default field initialization
Sometimes you want to set default values for some fields if not all parameters are passed to the constructor. For example, if e-mail isn't required:
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "unknown@noemail.com"; // Default value
}
4. Initialization via Object Initializer
With constructors, you can combine another handy syntax — object initializers. You can call the constructor, and then list property values in curly braces for the new object:
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
// Constructor is still recommended
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "";
}
}
Student s = new Student("Anton", 18) { Email = "anton@domain.com" }; // constructor + properties
This syntax works great with a constructor when some parameters have default values or aren't always known at creation time.
5. Typical Mistakes and Gotchas
When working with constructors, newbies run into a few common mistakes. Let's break them down in plain English:
Mistake #1: Name mismatch
Sometimes people mix up parameter and field names, especially if they only differ by case.
public Student(string Name, int Age) // With capital letters!
{
Name = Name; // Oops! Both Name refer to the parameter. The field stays uninitialized.
}
How to do it right: Use this to refer to the object's field:
public Student(string name, int age)
{
this.Name = name;
this.Age = age;
}
Or just pick different names (like nameParam, ageParam), but using this. is considered good style, especially in big projects.
Mistake #2: No default constructor
If you declare at least one constructor, and then try to create an object with no parameters — you'll get a compile error:
public class Student
{
public Student(string name) { /*...*/ }
}
// somewhere in the code
Student s = new Student(); // Error! No parameterless constructor.
Solution: Explicitly add a parameterless constructor:
public Student() { /*...*/ }
Mistake #3: Infinite recursion — if a constructor calls itself
public Student()
{
// Error! Calls itself — infinite recursion.
new Student();
}
GO TO FULL VERSION