The Constructor as a Method

A Constructor with Parameters

In your class, you can create a constructor with as many parameters as you want. Here is an example of a constructor that uses three parameters:

public class Exercise
{
    public Exercise(string a, int b, int c)
    {
    }
}

In the body of the constructor, you can ignore or use the values of the parameters. To create an object of the class, declare a variable of the class and initialize it using the constructor. This means that you must pass an argument for each parameter.

ApplicationPractical Learning: Introducing Object Construction

  1. Start Microsoft Visual Studio and create a new Console App (that support the .NET 6.0 (Long-Term Support) named Chemistry2
  2. In the Solution Explorer, right-click Chemistry2 -> Add -> Class...
  3. In the middle list of the Add New Item dialog box, make sure Class is selected.
    Change the file Name to Element
  4. Press Enter
  5. Based on what we learned in the previous lesson, change the Element class as follows:
    namespace Chemistry2
    {
        public class Element
        {
            internal string Symbol       { get; set; }
            internal string ElementName  { get; set; }
            internal int    AtomicNumber { get; set; }
            internal double AtomicWeight { get; set; }
    
            public Element()
            {
                Symbol = "H";
                ElementName = "Hydrogen";
                AtomicNumber = 1;
                AtomicWeight = 1.008;
    	}
        }
    }
  6. In the Solution Explorer, right-click Program.cs -> Rename
  7. Type PeriodicTable (to get PeriodicTable.cs) and press Enter
  8. Read the content of the message box and click Yes
  9. Click the PeriodicTable.cs tab and change the document as follows:
    using Chemistry2;
    using static System.Console;
    
    Element h = new() { ElementName = "Hydrogen", AtomicWeight = 1.008, AtomicNumber = 1, Symbol = "H" };
    Element he = new() { ElementName = "Helium", AtomicWeight = 4.002602, AtomicNumber = 2, Symbol = "He" };
    Element li = new() { ElementName = "Lithium", AtomicWeight = 6.94, AtomicNumber = 3, Symbol = "Li" };
    Element be = new();
    
    be.Symbol = "Be";
    be.AtomicNumber = 4;
    be.ElementName = "Beryllium";
    be.AtomicWeight = 9.0121831;
    
    Element b = new() { ElementName = "Boron", AtomicWeight = 10.81, AtomicNumber = 5, Symbol = "B" };
    Element c = new() { Symbol = "C", AtomicNumber = 6, ElementName = "Carbon", AtomicWeight = 12.011 };
    Element n = new() { AtomicNumber = 7, Symbol = "N", ElementName = "Nitrogen", AtomicWeight = 14.007 };
    
    WriteLine("Chemistry");
    WriteLine("------------------------");
    WriteLine("Symbol:        " + n.Symbol);
    WriteLine($"Atomic Number: {n.AtomicNumber}");
    WriteLine("Element Name:  " + n.ElementName);
    WriteLine($"Atomic Weight: " + n.AtomicWeight);
    Write("========================");
  10. To execute the project, press Ctrl + F5:
    Chemistry
    ------------------------
    Symbol:        N
    Atomic Number: 7
    Element Name:  Nitrogen
    Atomic Weight: 14.007
    ========================
    
    Press any key to close this window . . .
  11. To close the window and return to your programming environment, press U
  12. To create and use a Constructor with many parameters, click the Element.cs tab to access the class and change it as follows:
    namespace Chemistry2
    {
        public class Element
        {
            internal string Symbol       { get; set; }
            internal string ElementName  { get; set; }
            internal int    AtomicNumber { get; set; }
            internal double AtomicWeight { get; set; }
    
            public Element(int number, string symbol, string name, double mass)
            {
                Symbol = symbol;
                ElementName = name;
                AtomicWeight = mass;
                AtomicNumber = number;
    	}
        }
    }
  13. Click the Chemistry.cs tab and change the code as follows:
    using Chemistry2;
    using static System.Console;
    
    Element h = new Element(1, "H", "Hydrogen", 1.008);
    Element he = new Element(2, "He", "Helium", 4.002602);
    Element li = new Element(3, "Li", "Lithium", 6.94);
    Element be = new(4, "Be", "Beryllium", 9.0121831);
    Element b = new(5, "B", "Boron", 10.81);
    Element n = new(7, "N", "Nitrogen", 14.007);
    
    Element o = new(8, "O", "Oxygen", 15.999);
    
    WriteLine("Chemistry");
    WriteLine("------------------------");
    WriteLine("Symbol:        " + n.Symbol);
    WriteLine($"Atomic Number: {n.AtomicNumber}");
    WriteLine("Element Name:  " + n.ElementName);
    WriteLine($"Atomic Weight: " + n.AtomicWeight);
    Write("========================");
  14. To execute the application and see the result, on the main menu, click Debug -> Start Without Debugging:
    Chemistry
    ------------------------
    Symbol:        O
    Atomic Number: 8
    Element Name:  Oxygen
    Atomic Weight: 15.999
    ========================
    
    Press any key to close this window . . .
  15. To close the window and return to your programming environment, press J

Passing an Argument by Name

As seen with methods, if you call a constructor that takes at least one argument, you can access the/each parameter by its name, followed by a colon, and its value. Here is an example:

using static System.Console;

Element c = new(name: "Carbon", mass: 12.011, symbol: "C", number: 6);

Constructor Overloading

In your class, you can create as many constructors as you want. If you decide to create different constructors, they must follow the rules of method overloading. This means that each constructor must be different from the others. To take care of this, each constructor can use a different number of parameters or different data types for parameters compared to other constructors. Here are examples:

public class Exercise
{
    public Exercise(string a)
    {
    }

    public Exercise(string a, int b, int c)
    {
    }
}

If you create different constructors, when creating (an) instance(s) of the class (when declaring a (the) variable(s) of the class), you can choose what constructor is appropriate to initialize the variable.

Consider the following class and its constructor:

public class Element
{
    string _name_;
    string _symbol_;
    int    _number_;
    double _weight_;

    public Element(int number, string symbol, string name, double mass)
    {
        _name_   = name;
        _weight_ = mass;
        _symbol_ = symbol;
        _number_ = number;
    }
}

If you create a class with only one constructor, when declaring an instance of the class, you must use that constructor: you cannot use the default constructor that doesn't use any parameter. When declaring the variable, initialize it with a constructor with parentheses and provide the value(s) in the parentheses of the constructor.

ApplicationPractical Learning: Overloading a Constructor

  1. Click the Element.cs tab and change its class as follows:
    namespace Chemistry2
    {
        public class Element
        {
            internal string Symbol       { get; set; }
            internal string ElementName  { get; set; }
            internal int    AtomicNumber { get; set; }
            internal double AtomicWeight { get; set; }
    
            public Element(int number)
            {
                AtomicNumber = number;
            }
    
            public Element(string symbol)
            {
                Symbol = symbol;
            }
    
            public Element(int number, string symbol, string name, double mass)
            {
                Symbol = symbol;
                ElementName = name;
                AtomicWeight = mass;
                AtomicNumber = number;
    	}
        }
    }
  2. Click the Chemistry.cs tab and change the code of the Click event as follows:
    using Chemistry2;
    using static System.Console;
    
    Element h = new Element(1, "H", "Hydrogen", 1.008);
    Element he = new Element(2, "He", "Helium", 4.002602);
    Element li = new Element(3, "Li", "Lithium", 6.94);
    Element be = new(4, "Be", "Beryllium", 9.0121831);
    Element b = new(5, "B", "Boron", 10.81);
    Element c = new(name: "Carbon", mass: 12.011, symbol: "C", number: 6);
    Element n = new(7, "N", "Nitrogen", 14.007);
    Element o = new(8, "O", "Oxygen", 15.999);
    
    Element f = new Element(9);
    f.Symbol = "F";
    f.AtomicWeight = 18.998;
    f.ElementName = "Fluorine";
    
    Element ne = new Element("Ne");
    ne.AtomicNumber = 10;
    ne.AtomicWeight = 20.180;
    ne.ElementName = "Neon";
    
    WriteLine("Chemistry");
    WriteLine("------------------------");
    WriteLine("Symbol:        " + f.Symbol);
    WriteLine($"Atomic Number: {f.AtomicNumber}");
    WriteLine("Element Name:  " + f.ElementName);
    WriteLine($"Atomic Weight: " + f.AtomicWeight);
    WriteLine("========================");
    
    WriteLine("Symbol:        " + ne.Symbol);
    WriteLine($"Atomic Number: {ne.AtomicNumber}");
    WriteLine("Element Name:  " + ne.ElementName);
    WriteLine($"Atomic Weight: " + ne.AtomicWeight);
    Write("========================");
  3. To execute the application, on the main menu, click Debug -> Start Without Debugging:
    Chemistry
    ------------------------
    Symbol:        F
    Atomic Number: 9
    Element Name:  Fluorine
    Atomic Weight: 18.998
    ========================
    Symbol:        Ne
    Atomic Number: 10
    Element Name:  Neon
    Atomic Weight: 20.18
    ========================
    
    Press any key to close this window . . .
  4. To close the window and return to your programming environment, press M

A Boolean Parameter in a Constructor

A constructor can use a Boolean parameter. Here is an example:

public class Contractor
{
    public Contractor(bool validated)
    {
    }

    void CalculatePayroll(bool fullTime)
    {
    }

    void ValidateEmploymentStatus()
    {
        CalculatePayroll(true);
    }
}

public class Accountability
{
    public Accountability()
    {
        Contractor empl = new Contractor(true);

        var staff = new Contractor(false);
    }
}

The Absence of a Default Constructor

If you create a class with only one constructor and that constructor uses at least one parameter, the default constructor would not be available anymore. If you want to access a default constructor of an object, you have two options:

A class is usually made to contain many members. The primary reason you create a constructor is to have a tool to initialize an object of the class with one or some default values. The primary reason you create different constructors is to provide different values to objects depending on what constructor a user (actually a programmer) wants to use to create an object. To make this happen, you can initialize the members with values passed to the parameter(s). Here are examples:

using static System.Console;

WriteLine("Using Constructors");
WriteLine("==================================");
Exercise exo = new Exercise();
exo = new Exercise("C# Programming");
exo = new Exercise("A wondewrful world", 248);
exo = new Exercise("A programming endevour", 557, 3972);

public class Exercise
{
    string text;
    int    wdt, hgt;

    public Exercise()
    {
        text = "Empty";

        WriteLine("Default constructor");
        WriteLine("----------------------------------");
        WriteLine($"Contents:    {text}");
        WriteLine($"Dimension 1: {wdt}");
        WriteLine($"Dimension 2: {hgt}");
        WriteLine("==================================");
    }

    public Exercise(string title)
    {
        text = title;

        WriteLine("A constructor with one argument");
        WriteLine("----------------------------------");
        WriteLine($"Contents:    {text}");
        WriteLine($"Dimension 1: {wdt}");
        WriteLine($"Dimension 2: {hgt}");
        WriteLine("==================================");
    }

    public Exercise(string title, int width)
    {
        wdt = width;
        text = title;

        WriteLine("A constructor with two arguments");
        WriteLine("----------------------------------");
        WriteLine($"Contents:    {text}");
        WriteLine($"Dimension 1: {wdt}");
        WriteLine($"Dimension 2: {hgt}");
        WriteLine("==================================");
    }

    public Exercise(string title, int width, int height)
    {
        text = title;
        wdt  = width;
        hgt  = height;

        WriteLine("A constructor with three arguments");
        WriteLine("----------------------------------");
        WriteLine($"Contents:    {text}");
        WriteLine($"Dimension 1: {wdt}");
        WriteLine($"Dimension 2: {hgt}");
        WriteLine("==================================");
    }
}

A Constructor with Default Values

Since a constructor is primarily a method, its parameter(s), if any, can use default values. The rules are exactly the same we reviewed for methods. To provide a default value for the parameter of a constructor, assign the desired but appropriate value to the parameter when creating the constructor. Here is an example:

public class Exercise
{
    public Exercise(string caption = "Exercise")
    {
    }
}

Once again, in the body of the constructor, you can use or ignore the parameter. If you create one constructor and it uses one parameter, when creating an object of the class, that single constructor would act as both (or either) a default constructor and (or) a constructor that uses one parameter. This means that you can declare a variable and use a constructor with empty parentheses. Here is an example:

using static System.Console;

public class Employee
{
    public Employee(string name = "John Doe")
    {
        WriteLine("==================================");
        WriteLine($"Employee Name: {name}");
        WriteLine("==================================");
    }
}

Employee staff = new Employee();

In the same way, you can create a constructor that uses different parameters and some parameters can have default values. When doing this, make sure you follow the rules we reviewed for functions (or methods) that have default values for parameters. Here is an example:

using static System.Console;

public class Employee
{
    public Employee(int nbr = 111_111, string fname = "John",
                    string lname = "Doe", double hsal = 0.00)
    {
        WriteLine("==================================");
        WriteLine($"Employee #:    {nbr}");
        WriteLine($"Employee Name: {fname} {lname}");
        WriteLine($"Hourly Salary: {hsal}");
    }
}

// Creating an object without arguments
Employee staff = new Employee();
        
// Passing one argument
staff = new Employee(283_583);
// Passing three arguments
staff = new Employee(928_495, "James", "Dickson");
// Passing all arguments
staff = new Employee(492_859, "Elisabeth", "Hoppers", 22.28);
// Passing arguments by names
staff = new Employee(lname: "Turner", nbr: 592_804, hsal: 17.85, fname: "Chritian");
WriteLine("==================================");

This would produce:

==================================
Employee #:    111111
Employee Name: John Doe
Hourly Salary: 0
==================================
Employee #:    283583
Employee Name: John Doe
Hourly Salary: 0
==================================
Employee #:    928495
Employee Name: James Dickson
Hourly Salary: 0
==================================
Employee #:    492859
Employee Name: Elisabeth Hoppers
Hourly Salary: 22.28
==================================
Employee #:    592804
Employee Name: Chritian Turner
Hourly Salary: 17.85
==================================

Press any key to close this window . . .

The Destruction of an Object

The Destructor of a Class

A destructor is a special method of a class. While a constructor is called when an object is created, a destructor is called when an object is not used anymore. The job of a destructor is to do the cleaning of the computer memory that an object was occupying when the object was used. Like the default constructor, the compiler always creates a default destructor if you don't create one. Unlike the constructor, the destructor cannot be overloaded. This means that, if you decide to create a destructor, you can have only one. Like the default constructor, a destructor also has the same name as its class. This time, the name of the destructor starts with a tilde "~".

To create a destructor, type ~ followed by the name of the class. Here is an example:

public class Exercise
{
    public Exercise(string caption = "Exercise", int width = 640, int height = 480)
    {
    }

    ~Exercise()
    {
    }
}

Garbage Collection

When you initialize a variable using the new operator, you are in fact reserving some space in the section of memory called the heap. Such memory is "allocated" for the variable. When that variable is no longer needed, such as when your program closes, the variable must be removed from memory and the space it was using should (must) be made available to other variables or other programs. In fact, when an object has been removed from memory, it is replaced by garbage, which is some value but that is of no use (that area of memory becomes filled with garbage). If you program in some languages such as C/C++, Assembly, Pascal, etc, you should (must) find a way to remove that garbage (it is not difficult, sometimes it takes a simple/single line of code, but you should (must) remember to do it); that is, you should (must) free the memory a variable (declared with new, and called a reference) was using. Freeing the memory is referred to as garbage collection. Normally, in languages like C++ or Pascal, that's one of the ways you use a destructor.

The .NET library solves the problem of garbage collection by "cleaning" the memory after you. This is done automatically when necessary so that the programmer doesn't need to worry about this issue.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2001-2022, C# Key Wednesday 24 November 2021 Next