Techniques of Creating and Using a Constructor

A Constructor with No Body

As mentioned for functions (and methods), if you are creating a small constructor that contains a single statement, you can replace the curly brackets with the => operator after the parentheses of the name of the constructor. This is followed by the necessary one-line statement.

ApplicationPractical Learning: Introducing Constructors

  1. Start Microsoft Visual Studio and create a new Console App named Geometry1 that supports .NET 7.0 (Standard Term Support)
  2. To create a new folder, in the Solution Explorer, right-click Geometry1 -> Add -> New Folder
  3. Type Models as the name of the folder
  4. In the Solution Explorer, right-click the second Models -> Add -> Class...
  5. Change the name to EquilateralTriangle
  6. Click Add
  7. Change the document and the class as follows:
    namespace Geometry1.Models
    {
        public class EquilateralTriangle
        {
            private double s;
            const double NumberOfSides = 3;
    
            public EquilateralTriangle()
            {
                s = 0;
            }
    
            public EquilateralTriangle(double side)
            {
                s = side;
            }
    
            public double CalculatePerimeter()
            {
                double dResult = 0;
    
                dResult = s * NumberOfSides;
    
                return dResult;
            }
        }
    }
  8. In the Solution Explorer, right-click program.cs and click Rename
  9. Type EuclideanShape (to get EuclideanShape.cs) and press Enter
  10. Read the message box and press Enter twice (to acess the EuclideanShape.cs tab)
  11. Change the document as follows:
    using Geometry1.Models;
    using static System.Console;
    
    EquilateralTriangle et = new();
    
    WriteLine("========================================");
    WriteLine("Enter the value to process the triangle");
    Write("Side:      ");
    double side = double.Parse(ReadLine());
    
    et = new EquilateralTriangle(side);
    
    WriteLine("========================================");
    WriteLine("Geometry - Equilateral Triangle");
    WriteLine("----------------------------------------");
    WriteLine("Side:      {0}", side);
    WriteLine("Perimeter: {0}", et.CalculatePerimeter());
    Write("========================================");
  12. To execute the application to test it, on the main menu, click Debug -> Start Without Debugging
  13. When requested, type the Side as 248.73 and press Enter:
    ========================================
    Enter the value to process the triangle
    Side:      248.73
    ========================================
    Geometry - Equilateral Triangle
    ----------------------------------------
    Side:      248.73
    Perimeter: 746.1899999999999
    ========================================
    
    Press any key to close this window . . .
  14. To close the window and return to your programming environment, press I
  15. Click the EquilateralTriangle.cs tab to access its class
  16. To create constructors that don't use a body, change the class as follows:
    namespace Geometry1.Models
    {
        public class EquilateralTriangle
        {
            private double s;
            const double NumberOfSides = 3;
    
            public EquilateralTriangle() => s = 0;
    
            public EquilateralTriangle(double side) => s = side;
    
            public double CalculatePerimeter() => s * NumberOfSides;
        [
    }
  17. To execute, press Ctrl + F5
  18. Type the Side as 8413.97 and press Enter
    ========================================
    Enter the value to process the triangle
    Side:      8412.97
    ========================================
    Geometry - Equilateral Triangle
    ----------------------------------------
    Side:      8412.97
    Perimeter: 25238.909999999996
    ========================================
    
    Press any key to close this window . . .
  19. Close the form and return to your programming environment
  20. Start a new Console App named PlanarCurves3 that uses the .NET 7.0 (Standard Term Support)
  21. To create a new folder, in the Solution Explorer, right-click PlanarCurves3 -> Add -> New Folder
  22. Type Models as the name of the folder
  23. In the Solution Explorer, right-click Models -> Add -> Class...
  24. Change the file Name to Circle
  25. Press Enter
  26. Change the document and the class as follows:
    namespace PlanarCurves3.Models
    {
        public class Circle
        {
            public const double PI = 3.14;
    
            public double Radius { get; set; }
    
            public Circle()
            {
                Radius = 0.00;
            }
    
            public double CalculateDiameter()
            {
                return Radius * 2.00;
            }
    
            public double CalculateArea()
            {
                return Radius * Radius * PI;
            }
        }
    }
  27. In the Solution Explorer, right-click Program.cs and click Rename
  28. Type Geometry (to get Geometry.cs) and press Enter
  29. Read the message in the message box and click Yes
  30. Click the Geometry.cs tab to access it
  31. Change the document as follows:
    using PlanarCurves3.Models;
    using static System.Console;
    
    var round = new Circle();
    
    WriteLine("=====================================");
    WriteLine("Enter the value to process the circle");
    Write("Radius:      ");
    round.Radius = double.Parse(ReadLine());
    
    WriteLine("=====================================");
    WriteLine("Geometry - Circle Summary");
    WriteLine("-------------------------------------");
    WriteLine("Radius:   {0}", round.Radius);
    WriteLine("Diameter: {0}", round.CalculateDiameter());
    WriteLine("Area:     {0}", round.CalculateArea());
    Write("=====================================");
  32. To execute the application, on the main menu, click Debug -> Start Without Debugging:
  33. When requested, type the Radius as 248.73 and press Enter:
    =====================================
    Enter the value to process the circle
    Radius:      248.73
    =====================================
    Geometry - Circle Summary
    -------------------------------------
    Radius:   248.73
    Diameter: 497.46
    Area:     194261.16450599997
    =====================================
    
    Press any key to close this window . . .
  34. To close the window, press Enter and return to your programming environment
  35. Click the Circle.cs tab to access the class

A Read-Only Field in a Class

When creating a field of a class, one of the decisions you must make is how the field would get its value(s). To create a field so that objects outside the class can only view its value but cannot change it while the value can be changed inside the class, create that field as read-only. To do this, when creating the field in the class, precede its data type with the readonly keyword. Here is an example:

public class Circle
{
    readonly double PI;
}

You can mark the field with an access level such as private or public, depending on your intentions.

To specify the value of a read-only field, use a constructor, such as the default constructor, to initialize the field. Here is an example:

public class Circle
{
    private double r;

    private readonly double PI;

    public Circle()
    {
       	PI = 3.14;
    }
}

The only difference between a constant variable and a read-only field is that a constant variable must be initialized when creating it. On the other hand, you can create more than one constructor in a class, then assign the same or a different value in each constructor to the read-only field. This means that, because you can initialize a read-only field in a constructor, if you have different constructors, you can also have different values for the same read-only field. Here are examples:

public class Circle
{
    private double r;

    private readonly double PI;

    public Circle()
    {
       	PI = 3.14;
    }

    public Circle(double rad)
    {
       	r = rad;
        PI = 3.14159;
    }

    public double CalculateDiameter()
    {
       	return r * 2;
    }

    public double CalculateArea()
    {
       return r * r * PI;
    }
}

Instead of a constant value, the value of a read-only field can come from an expression. If the value held by a read-only field is gotten from an expression, then the field must be initialized in the(a) construction with the desired expression.

We know that a constant variable must be initialized when it is created. Although a read-only variable seems to follow the same rule, it doesn't. Remember that you don't need to initialize a read-only variable when you declare it since you can do this in the(a) constructor of the class. Also, because a constructor can be overloaded, a read-only field can hold different values depending on the particular constructor that is accessed at a particular time, but the value of a constant variable cannot change: it is initialized once, in the class (or in a method) and it keeps that value throughout the class (or method).

ApplicationPractical Learning: Creating and Using a Read-Only Field

  1. You can initialize a read-only field in the (a) constructor of its class. For an example, change the Circle class as follows:
    namespace PlanarCurves3.Models
    {
        public class Circle
        {
            public readonly double PI;
    
            public double Radius { get; set; }
    
            public Circle()
            {
                PI = 3.14;
                Radius = 0.00;
            }
    
            public double CalculateDiameter()
            {
                return Radius * 2.00;
            }
    
            public double CalculateArea()
            {
                return Radius * Radius * PI;
            }
        }
    }
  2. Click the Geometry.cs tab
  3. Change the code of the event as follows:
    using PlanarCurves3.Models;
    using static System.Console;
    
    var round = new Circle();
    
    WriteLine("=====================================");
    WriteLine("Enter the value to process the circle");
    Write("Radius:   ");
    round.Radius = double.Parse(ReadLine());
    
    WriteLine("=====================================");
    WriteLine("Geometry - Circle Summary");
    WriteLine("-------------------------------------");
    WriteLine("Radius:   {0}", round.Radius);
    WriteLine("PI:       {0}", round.PI);
    WriteLine("Diameter: {0}", round.CalculateDiameter());
    WriteLine("Area:     {0}", round.CalculateArea());
    Write("=====================================");
  4. To execute the application, on the main menu, click Debug -> Start Without Debugging:
  5. For the Side, type 5377.96 and press Enter:
    =====================================
    Enter the value to process the circle
    Radius:   5377.96
    =====================================
    Geometry - Circle Summary
    -------------------------------------
    Radius:   5377.96
    PI:       3.14
    Diameter: 10755.92
    Area:     90816504.811424
    =====================================
    
    Press any key to close this window . . .
  6. To close the window and return to your programming environment, press K
  7. Click the Circle.cs tab to access the class
  8. Because a read-only field can be initialized in a constructor, each constructor can assign a different value to the field. As a result, a read-only field can have different values. When you create an object, the constructor you choose will provide the value of the read-only field. For examples, change the Circle class as follows:
    namespace PlanarCurves3.Models
    {
        public class Circle
        {
            public readonly double PI;
    
            public double Radius { get; set; }
    
            public Circle()
            {
                PI = 3.14;
                Radius = 0.00;
            }
    
            public Circle(double rad)
            {
                Radius = rad;
                PI = 3.14159;
            }
    
            public double CalculateDiameter()
            {
                return Radius * 2.00;
            }
    
            public double CalculateArea()
            {
                return Radius * Radius * PI;
    	}
        }
    }
  9. Click the Geometry.cs tab to access the code
  10. Change the code as follows:
    using PlanarCurves3.Models;
    using static System.Console;
    
    WriteLine("=====================================");
    WriteLine("Enter the value to process the circle");
    Write("Radius:   ");
    double rad = double.Parse(ReadLine());
    
    var round = new Circle(rad);
    
    WriteLine("=====================================");
    WriteLine("Geometry - Circle Summary");
    WriteLine("-------------------------------------");
    WriteLine("Radius:   {0}", round.Radius);
    WriteLine("PI:       {0}", round.PI);
    WriteLine("Diameter: {0}", round.CalculateDiameter());
    WriteLine("Area:     {0}", round.CalculateArea());
    Write("=====================================");
  11. To execute the project, on the main menu, click Debug -> Start Without Debugging
  12. For the Side, type 1327.97
    =====================================
    Enter the value to process the circle
    Radius:   1327.97
    =====================================
    Geometry - Circle Summary
    -------------------------------------
    Radius:   1327.97
    PI:       3.14159
    Diameter: 2655.94
    Area:     5540207.539496231
    =====================================
    
    Press any key to close this window . . .
  13. To close the window and return to your programming environment, press K
  14. Start a new Console App that support .NET 7.0 (Standard Term Support) and named Volumetrics1
  15. To create a new folder, in the Solution Explorer, right-click Volumetrics1 -> Add -> New Folder
  16. Type Models as the name of the folder
  17. In the Solution Explorer, right-click Models -> Add -> Class...
  18. In the middle list of the Add New Item dialog box, make sure the Class option is selected.
    Change the file Name to Rectangle
  19. Click Add

Using a Reference of a Class Without its Object

Introduction

So far, to create an object, we had to declare a variable of the desired class. A variable, or object, is necessary only if you are planning to use the object more than once. If you need a reference to the object only once (or just a few times), you don't need a variable. In this case, in the section of code where you want the reference, simply type the new keyword followed by the name of the class. Since you are calling a constructor of the class, you must add parentheses. Here is an example:

public class Triangle
{
    public double Width { get; set; }
    public double Depth { get; set; }


    public double CalculateArea() => Width * Depth / 2.00;
}

. . .

new Triangle();

In the same way, you can call such a reference as many times as you want. Since you are getting an object that is a reference to the class, you can then access any public or internal members of that class. Here are examples that access a field, a property, and methods of the class:

using PlanarCurves3.Models;
using static System.Console;

WriteLine("=====================================");
WriteLine("Enter the value to process the circle");
Write("Radius:      ");
double rad = double.Parse(ReadLine());

WriteLine("=====================================");
WriteLine("Geometry - Circle Summary");
WriteLine("-------------------------------------");
WriteLine("Radius:   {0}", new Circle(rad).Radius);
WriteLine("PI:       {0}", new Circle(rad).PI);
WriteLine("Diameter: {0}", new Circle(rad).CalculateDiameter());
WriteLine("Area:     {0}", new Circle(rad).CalculateArea());
Write("=====================================");

To make your code easy to read, you should put the new operator and the name of the class in parentheses. Here are examples:

using PlanarCurves3;
using static System.Console;

WriteLine("=====================================");
WriteLine("Enter the value to process the circle");
Write("Radius:      ");
double rad = double.Parse(ReadLine());

WriteLine("=====================================");
WriteLine("Geometry - Circle Summary");
WriteLine("-------------------------------------");
WriteLine("Radius:   {0}", (new Circle(rad)).Radius);
WriteLine("PI:       {0}", (new Circle(rad)).PI);
WriteLine("Diameter: {0}", (new Circle(rad)).CalculateDiameter());
WriteLine("Area:     {0}", (new Circle(rad)).CalculateArea());
Write("=====================================");

Passing a Reference to a Method

As mentionned with functions, normally, a method can return only one value. Sometimes, you want a method to return many values. When studying functions, we saw that one way to solve this problem is to pass one or more arguments as references to a method. You proceed exactly as we saw with functions.

Returning a Reference

As done for a value of a regular type, you can return an object value from a method of a class. To do this, you can first declare the method and specify the class as the return type. Here is an example:

public class Triangle
{
    public double Width { get; set; }
    public double Depth { get; set; }

    public Triangle(double w, double d)
    {
        Width = w;
        Depth = d;
    }

    public double CalculateArea() => Width * Depth / 2.00;
}

public class Shape
{
    private Triangle Create()
    {
        double width = 2834.208;
        double depth = 602.415;

        return new Triangle(width, depth);
    }
}

A Class as a Type

A Field of a Class Type

Just like a primitive type can be used to describe an object, a class can play that role too. To make this happen, create a member that uses a class as its type. You can use any class, including one you create yourself. Here is an example:

class Rectangle
{
    double _width_;
    double _height_;
}

class Box
{
    Rectangle face;
}

You can mark the field with an access level such as private, public or internal, etc.

Of course, the class can also have members (fields and properties) of any type. Here is an example:

public class Rectangle
{
    double _width_;
    double _height_;
}

public class Box
{
    double _depth_;
    Rectangle _face_;
}

If a member of a class A (for example, the above Box class) is of a class type B (for example, the above Rectangle class):

A Property of a Class Type

The data type of a property can be a class. If you want to create a complete property, you can first create a field as we saw in the previous sections. In the get accessor of the property, you can return the field. In the set accessor, you assign value to the field. Here is an example:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

public class Equation
{
    private Point _pt_;

    public Point Operand
    {
        get
        {
            return _pt_;
        }

        set
        {
            _pt_ = value;
        }
    }
}

In earlier sections, we saw that you should/must initialize the field, which you can do in a constructor for the class. After that, you can use the property. To access a member of the class of the property, you can use the period operator. Here is an example:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

public class Equation
{
    private Point _pt_;

    public Equation()
    {
        _pt_ = new Point(0, 0);
    }

    public Point Operand
    {
        get
        {
            return _pt_;
        }

        set
        {
            _pt_ = value;
        }
    }
}

After that, you can use the property. To access a member of the class of the property, you can use the period operator. Here is an example:

using static System.Console;

using CoordinateSystem;

Algebra.Equation eq = new Algebra.Equation(2, 3, 18);

WriteLine("Equation: {0}", eq.Create());
WriteLine("-----------------------------");

eq.Operand = new Point(3, -5);
eq.Result = -10;

WriteLine("Equation: {0}", eq.Create());
WriteLine("-----------------------------");

eq.Operand.X = 5;
eq.Operand.Y = -3;
eq.Result = -15;

WriteLine("Equation: {0}", eq.Create());
WriteLine("=============================");

namespace CoordinateSystem
{
    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }

        public Point(int x, int y)
        {
            X = x;
            Y = y;
        }
    }
}

namespace Algebra
{
    public class Equation
    {
        private Point _pt_;

        public Equation(int factor1, int factor2, int result)
        {
            Result = result;
            _pt_  = new Point(factor1, factor2);
        }

        public Point Operand
        {
            get
            {
                return _pt_;
            }

            set
            {
                _pt_ = value;
            }
        }

        public int Result { get; set; }

        public string Create()
        {
            if( _pt_.Y >= 0 )
                return _pt_.X + "x + " + _pt_.Y + "y = " + Result;

            return _pt_.X + "x - " + (_pt_.Y * -1) + "y = " + Result;
        }
    }
}

This would produce:

Equation: 2x + 3y = 18
-----------------------------
Equation: 3x - 5y = -10
-----------------------------
Equation: 5x - 3y = -15
=============================

Press any key to close this window . . .

A Property or Field with the Same Type and Name

A property or a field of a class type can use the same name as the class. Here is an example for a field:

class Employee
{
}

class TimeSheet
{
    private double timeWorked;
    private string filingStatus;

    public Employee Employee;
}

In this case, the compiler would know that the first name represents a type and the second name represents a member of the class. In the methods of the class, when you use the name as variable, the compiler would know that you are accessing the member.

ApplicationPractical Learning: Using a Property of a Class Type

  1. Change the document and class as follows:
    namespace Volumetrics1.Models
    {
        public class Rectangle
        {
            public double Width  { get; set; }
            public double Height { get; set; }
        }
    }
  2. In the Solution Explorer, right-click Volumetrics1 -> Add -> Class...
  3. In the middle list, make sure Class is selected.
    Change the name to Box
  4. Press Enter
  5. Right-click in the Code Editor and click Remove and Sort Usings
  6. Type the code as follows:
    namespace Volumetrics1
    {
        public class Box
        {
            public double Depth { get; set; }
            public Rectangle Face { get; set; }
        }
    }
  7. In the Solution Explorer, right-click Program.cs and click Rename
  8. Type Geometry (to get Geometry.cs) and press Enter
  9. Read the message box and click Yes
  10. In the Solution Explorer, right-click Geometry.cs and click Open
  11. Implement the event as follows:
    using Volumetrics1.Models;
    using static System.Console;
    
    Box rectangular = new Box();
    rectangular.Face = new Rectangle();
    
    WriteLine("=====================================");
    WriteLine("Enter the value to process the box");
    Write("Width:       ");
    double width = double.Parse(ReadLine());
    Write("Height:      ");
    double height = double.Parse(ReadLine());
    Write("Depth:       ");
    double depth = double.Parse(ReadLine());
    
    rectangular.Face.Width = width;
    rectangular.Face.Height = height;
    rectangular.Depth = depth;
    
    double frontBackPerimeter = (rectangular.Face.Width + rectangular.Face.Height) * 2;
    double leftRightPerimeter = (rectangular.Face.Height + rectangular.Depth) * 2;
    double topBottomPerimeter = (rectangular.Face.Width + rectangular.Depth) * 2;
    
    WriteLine("=====================================");
    WriteLine("Geometry - Box Summary");
    WriteLine("-------------------------------------");
    WriteLine("Width:       {0}", rectangular.Face.Width);
    WriteLine("Height:      {0}", rectangular.Face.Height);
    WriteLine("Depth:       {0}", rectangular.Depth);
    WriteLine("=====================================");
    WriteLine("Perimeters");
    WriteLine("-------------------------------------");
    WriteLine("Front Back:  {0}", frontBackPerimeter);
    WriteLine("Left Right:  {0}", leftRightPerimeter);
    WriteLine("Top Bottom:  {0}", topBottomPerimeter);
    WriteLine("=====================================");
  12. To execute the project, on the main menu, click Debug -> Start Without Debugging
  13. When requested, for the Width, type 137.58 and press Enter
  14. For the Height, type 69.33 and press Enter
  15. For the Depth, type 88.97 and press Enter:
    =====================================
    Enter the value to process the box
    Width:       137.58
    Height:      69.33
    Depth:       88.97
    =====================================
    Geometry - Box Summary
    -------------------------------------
    Width:      137.58
    Height:     69.33
    Depth:      88.97
    =====================================
    Perimeters
    -------------------------------------
    Front Back: 413.82000000000005
    Left Right: 316.6
    Top Bottom: 453.1
    =====================================
    
    Press any key to close this window . . .
  16. To close the window and return to your programming environment, press Enter
  17. Close your programming environment

Previous Copyright © 2001-2023, C# Key Saturday 29 April 2023 Next