Tech Point Fundamentals

Tuesday, December 22, 2020

Constructors in C# | Default, Static, Private, Copy Constructor

Constructors in C# | Default Constructor | Static Constructor | Private Constructor | Copy Constructor | Constructor Chaining

Constructors-In-C#

A constructor is a special method that is used to initialize the data members or fields of the class or structure while creating the object of the class or structure. Constructors are invoked automatically at the time of object creation. 




Constructor

A constructor is nothing but a method without any return type which has the same name as the class or struct name. Constructors are called automatically when we create the object of the class.

 When we have not created any constructor in the class or structure, the compiler will automatically create a default constructor of the class or structure. Memories are allocated for the class when the constructors are called.

Constructors allow the developers to set default values, limit instantiation, and write code that is flexible and easy to read. 

One of the common uses of a constructor is to initialize the read-only fields in C# because read-only fields can only be initialized either at the time of declaration or in the constructor. Constructors are also used in dependency injection.



Constructor Fundamental Points

    1. All the constructors have the same name as the class or structure name.
    2. Both classes and structures can have constructors. But an interface cannot have any constructor at all.
    3. All the constructors are private by default. However, all the access modifiers can be used in the constructor declaration to control its access.
    4. A class or structure can have any number of constructors.
    5. Constructors can have a throw clause which means we can throw an exception from the constructor.
    6. All the constructors can have parameters except the static constructor.
    7. Constructors cannot be called explicitly, they are invoked automatically when the object is created.
    8. All classes and structures have a default constructor if you do not create a constructor yourself.
    9. Constructors are always executed before any method or property. 
    10. Base class constructors are always called before any of the child class constructors.
    11. Constructors are never inherited.



Constructor Fundamental Rules

    1. The constructor name must be the same as the type name (class, struct).
    2. A constructor cannot have a return type even void
    3. In the constructor return statement with a value is not allowed but you can have a return; statement.
    4. A constructor cannot have any modifiers like virtual, abstract, final, sealed, or synchronized.
    5. Only one static constructor is allowed in any class or structure and a static constructor cannot have any parameter.
    6. It is not allowed to define a method with the same name as the class name in C#.
    7. Both OUT and REF-type parameters are allowed in constructors.
    8. Both PARAMS and OPTIONAL parameters are also allowed in constructors.
    9. A constructor can call other methods of the class.
    10. A structure cannot have an explicit default instance constructor but it can have a static constructor.
    11. A static class can have only one parameterless static constructor, not any instance constructor.
    12. A sealed class can have both static and instance constructors.
    13. A partial class can also define constructors.

Related Articles




Classifications of Constructors

Constructors can be classified into two broader categories:

A. Parameterless Constructor

A constructor without any parameter is known as a parameterless constructor. It is used to initialize the fields with default values.

In the given below example, the User(), public SuperAdmin() and MyStructure() constructors are parameterless constructors.

B. Parameterized Constructor

A constructor having at least one parameter is known as a parameterized constructor. It is used to initialize the data members or fields with different values for different objects.

You can define OUT and REF-type parameters in constructors. The PARAMS and OPTIONAL parameters are also allowed in constructors.

In the given example below, the User(string userName, string password), public SuperAdmin(string accessArea, string accessCode), and MyStructure(string inputParameter) constructors are parameterized constructors.

Now again the above classifications can be divided into two sub-categories:



i). Instance Constructor

Instance constructors are used for initializing the instance data member and fields of the class. All the non-static constructors are known as instance constructors.

Instance constructors can also be used to call the instance constructors of base classes. The derived class constructor can invoke the base class constructor through the base keyword.

When you create the instance of a class using a new operator, the following things happen internally:

    a) New memory is allocated for the object
    b) A new instance is created in the heap
    c) A reference is created into the stack and it is passed to the instantiated object.


In the given below example, all the constructors are instance constructors except the static User() constructor of the user class and the static MyStructure() constructor of the MyStructure structure.

ii). Non-Instance Constructors

Non-instance constructors are used for initializing the non-instanced (static) data members and fields of the class. All the static constructors are known as non-instance constructors.

In the given below example, only the static User() constructor of the user class and static MyStructure() constructor of the MyStructure structure are non-instance constructors.



Example


 

Types of Constructors

All the constructors fall under the above two categories. There can be the following constructors based on access modifiers, method modifiers, parameters, and functionality:

1. Default Constructor

   Default constructors are parameterless constructors. It can be divided into two categories again:



i). Implicit Default Constructor (System-Defined Default Constructor)

It is a special system-defined instance constructor without any parameter. When we do not create any constructor in the class, the compiler will automatically create a default constructor of the class. 

The system-defined default constructor initializes all numeric fields to zero and all string and object fields to null inside a class.

That default constructor simply invokes the parameterless constructor of the direct base class. If you have defined only a normal parameterized constructor in a base class and no explicit default constructor, in that case, the derived class cannot call the base class default constructor implicitly. You have to call the parameterized base class constructor explicitly from the derived class.

But in case you have not defined any explicit default constructor and only a parameterized constructor with params type parameters, in that case also the derived class calls the base class default constructor implicitly. There is no need to call the base class parameterized constructor explicitly.

If the class is abstract then the declared accessibility for the default constructor is protected, otherwise, the declared accessibility for the default constructor is public.

So, the default constructor is always of the form:
public C(): base() {}
protected C(): base() {}

In the above example, the MyStructure structure has an implicit default constructor. You cannot define any explicit default constructor.

ii). Explicit Default Constructor (User-Defined Default Constructor)

It is a user-defined instance constructor without any parameter. This can be used to initialize all the class instance fields with some default values. 

A structure cannot have an explicit default instance constructor but it can have a static constructor that is always parameterless.



In the above example User(), SuperAdmin(), and BaseClass() are explicit default constructors.


2. Static Constructor

Static constructors are parameterless non-instance constructors.  Static constructors are used to initialize a static class or static data members of a non-static class. 

Static constructors are invoked only once while creating the object of the non-static class or on the creation of the first reference to a static member.

    1. parameterized static constructor is not allowed.
    2. No access modifier is allowed for static constructors since they are private implicitly
    3. Static constructor overloading is not allowed
    4. Only a class or struct can contain a static constructor.
    5. A static constructor is never inherited since it is private implicitly.
    6. A static constructor can only access or initialize static data members.
    7. The static constructors are always called before any instance constructor.
    8. A static constructor can only access or initialize static data members.
    9. A static class can only have a static constructor.

In the above example, the non-instance User() and MyStructure() constructors are static constructors.



Please read more about the static constructor here. You can also read about the static constructor interview questions and answers here.


3. Private Constructor

If a constructor is created with a private access modifier, then it is known as a Private Constructor. A private constructor is a special instance constructor that is generally used in classes that contain static members only. 

If we do not use an access modifier with the constructor it will still be private by default. However, the private modifier is usually used explicitly to make it clear that the class cannot be instantiated.

Also a private constructor without having any parameters prevents the automatic generation of the default constructor.

    1. A private constructor is generally used for the singleton implementation.
    2. A class only having a default private constructor cannot be inherited.
    3. Private constructors are used to prevent the instantiation of a class.
    4. A class having only private constructors cannot be instantiated, except the nested class.



In the above example, the SuperAdmin() and Program() constructors are private constructors.


4. Copy Constructor

A Copy Constructor is a parameterized instance constructor that contains a parameter of the same class type. There is no inbuilt copy constructor provided by C# like C++, but we can implement the same based on our requirements.

If you remember, in C++ compiler creates a copy constructor if we don’t write our own copy constructor. 

This constructor creates an object by copying variables from another object. Its main use is to initialize a new instance to the values of an existing instance. 

In the above example, the User(User user) constructor is a copy constructor.




Constructor Overloading

A constructor can also be overloaded just like methods by using different signatures. A class or structure may have multiple constructors that take different arguments.

Constructor overloading is not much different than method overloading. In the case of method overloading you have multiple methods with the same name but different signatures, whereas in Constructor overloading you have multiple constructors with different signatures but the only difference is that Constructor doesn’t have a return type in C#.

In the above example, both the User class and SuperAdmin class have overloaded constructors.

Constructor overloading is used to pass different parameters based on requirements. For example, the SqlCommand  sealed class provides the following five overloaded constructors:

SqlCommand()
SqlCommand(string cmdText)
SqlCommand(string cmdText, SqlConnection connection)
SqlCommand(string cmdText, SqlConnection connection, SqlTransaction transaction)
SqlCommand(string cmdText, SqlConnection connection, SqlTransaction transaction,                                                         SqlCommandColumnEncryptionSetting columnEncryptionSetting)

You can also read about the method overriding here.



Constructor Chaining

Constructor Chaining is a way to invoke one constructor from another constructor. Constructor Chaining always happens in case of inheritance. If you do not specify anything the default is base.

To do constructor chaining we have to use this keyword after the constructor definition. We can also chain to the base class constructors by using the base keyword.

In constructor chaining, we must have to know the order of the execution sequence. A chained constructor is always called first. Circular chaining is not allowed.

We can use the constructor chaining for validation. Instead of duplicating the assignment and validation logic in all the constructors, we move it into a single constructor. And then call that constructor in other constructors. This also makes the code easier to maintain and understand.

In the above example, the SuperAdmin(string accessCode) constructor is calling the default constructor.




Constructor vs Method

  1. The constructor name must be the same as the class name while a method name may not be the same as the class name.
  2. A constructor cannot have any return types even void while a method must have a return type.
  3. A constructor is invoked automatically on an object creation while methods are called explicitly.
  4. Constructors are used to initialize the state of the class objects while methods are used to expose the behaviour of an object.
  5. A constructor can be used to restrict the instantiation of the class while a method can only be prevented from being accessed outside the class.



Delegate Constructor

Delegate Constructors are used to initialize a new delegate. It is defined in the System namespace which has two overloads:

protected Delegate (object target, string method);

It initializes a delegate that invokes the specified instance method on the specified class instance. This constructor cannot be used in application code.

protected Delegate (Type target, string method);

It initializes a delegate that invokes the specified static method from the specified class. This constructor also cannot be used in application code.

You can read more here.

Although it would not be very useful to have a delegate that points to a constructor, since constructors do not have a return value. You can't create a delegate around the constructor directly.

By using Reflection you can get the information about it with ConstructorInfo and not MethodInfo. The delegate would construct an object but give you no way of retaining a reference to it. You can of course create delegates that return the newly-constructed object. You could also create a delegate from the Invoke() method of the constructor's ConstructorInfo. Read more.

Instead of using slow Reflection, we can use Expression Trees in .NET 4 to create delegates for a standard constructor, a property getter, and a property setter without using Reflection at all. Read more




Live Demo


No comments:

Post a Comment

Please do not enter any HTML. JavaScript or spam link in the comment box.