Constructors are special functions that are executed to initialize the object's data members at creation.
Constructors have the same name of the class and do not have a return type.
class Employee
{
public Employee()
{
}
}
Constructor overloading
You can have more than one constructor with different parameter signature i.e. different number of parameters or different datatype arrangement.
class Employee
{
public Employee()
{
}
public Employee(string employeeName)
{
}
public Employee(string employeeName, decimal salary)
{
}
public Employee(decimal salary)
{
}
}
The default constructors
If you haven't defined ANY constructor in a non-static or non-abstract class, the compiler creates for you a public constructor with no parameter.
Structs do not accept explicit parameterless constructors although they have one by default. All data members of the struct must be explicitly assigned to value.
Base constructors
class Person
{
public Person()
{
}
public Person(string name)
{
}
}
class Employee : Person
{
public Employee()
{
}
}
Let's talk philosophy. You cannot have a glass of water before it has been a glass first. You cannot have an employee before he/she has been a person first.
So, in order to create an object as an Employee you have to create it first as a Person. Let's see code.
new Employee();
When this statement get executed; if you don't explicitly specify which base constructor to use, the default constructor will get executed if exist; otherwise, you will get a compiler error.
How to explicitly specify the base class constructor?
Simply you use the base keyword as follows.
class Employee : Person
{
public Employee() : base("No name")
{
}
}
You can also pass parameters from the current constructor to the base constructor as follows.
class Employee : Person
{
public Employee(string employeeName) : base(employeeName)
{
}
}
Actually, the concept of base constructors is not bound only to base class's constructors. It extends to current class's constructors.
The concept is simply you define a constructor to construct the object before it get constructed by the current constructor being executed.
You can make a constructor call another constructor in the same class as its base constructor using the this keyword. You can then make a chain of constructors.
class Emplyee : Person
{
public Employee() : this(0)
{
}
public Employee(decimal salary) : base("No name")
{
}
}
Static constructors
A static constructor gets executed directly before you first create an object of the class or access any of its static members. In fact it gets executed when loading the class definition in memory.
Static constructors increase performance with the fewest code. Another technique would be creating a "dirty-bit" to indicate whether the class has ever been used or not and keeping checking it in each constructor and static method and static property (note that this technique doesn't work with static fields of course).
Static constructors don't accept access modifiers or parameters, thus you will have only one static constructor per class/struct (no overloading). And you cannot call static constructors directly.
How constructors work?
- What happens when you execute something like
new Employee("abc");
You use the new keyword in constructor context so the runtime knows you want to create object of a class. - Then the runtime gets which type you want the object to be, here we want an Employee.
- The runtime allocates a location in memory which will hold the data and assign them to their default values.
- The runtime gets the constructor that matches the parameters you provide.
- The runtime executes the base constructor of the current constructor (if not specified, the default constructor is executed).
- Then the code of the current constructor gets executed.
- Then you get the reference to the object you've just created.
Keeping in mind that static constructors get executed at the first use of the class/struct.
Constructors and access modifiers
With the exception of static constructors and struct's constructors, you can define constructors with any access modifier (public, protected, internal, internal protected, private), see the Access modifiers post.
You make a protected constructor to use it as a base constructor of other constructors in derived classes. You can not make protected constructors in structs because there is no inheritance in structs.
You can do something like that.
class Employee
{
private Employee()
{
}
protected Employee(string employeeName)
{
}
}
Destructors
They are functions that get executed when the Garbage Collector collects objects. It's called automatically by the GC so you don't have control over when they get executed.
Destructors are used as cleanup functions you use to free up resources used by the object.
class Employee
{
~Employee()
{
}
}
Destructors are parameterless and have no return datatype. You can have only one destructor per class.
Another way to do this is using the IDisposable's Dispose() thus you may use the using statement. This is the recommended way to free up resources.
See destructors at the MSDN here.
A simple demo of constructors and destructors