Techniques of Creating and Using a Constructor

A Constructor with No Body

Consider a class with small constructors as follows:

@page
@model PracticalLearning.Pages.GeometryModel
@{
    EquilateralTriangle et = new();
    
    double side = 248.73;
    
    et = new EquilateralTriangle(side);
}

@functions{
    public class EquilateralTriangle
    {
        private double s;
        const double NumberOfSides = 3;

        // A parameter-less constructor
        public EquilateralTriangle()
        {
            s = 0;
        }

        // A constructor with one parameter
        public EquilateralTriangle(double side)
        {
            s = side;
        }

        public double CalculatePerimeter()
        {
            double dResult = 0;

            dResult = s * NumberOfSides;

            return dResult;
        }
    }
}

<pre>========================================
Geometry - Equilateral Triangle
----------------------------------------
Side:      @side
Perimeter: @et.CalculatePerimeter()
========================================</pre>

This would produce:

========================================
Enter the value to process the triangle
Side:      248.73
========================================
Geometry - Equilateral Triangle
----------------------------------------
Side:      248.73
Perimeter: 746.1899999999999
========================================

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. Here are examples:

@functions
{
    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;
        }
    }
}

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 a keyword named readonly. Here is an example:

@functions{
    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:

@functions{
    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:

@functions
{
    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).

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:

@page
@model Valuable.Pages.ExerciseModel
@{
    new Triangle();
}

@functions
{
    public class Triangle
    {
        public double Width { get; set; }
        public double Depth { get; set; }
        
        public double CalculateArea() => Width * Depth / 2.00;
    }
}

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. To make your code easy to read, you should put the new operator and the name of the class in parentheses. Here are examples that access a field, a property, and methods of the class:

@page
@model Valuable.Pages.ExerciseModel
@{
    double rad = 837.58;
}

@functions
{
    public class Circle
    {
        public const double PI = 3.14;

        public double Radius { get; set; }

        public Circle(double r)
        {
            Radius = r;
        }

        public double CalculateDiameter()
        {
            return Radius * 2.00;
        }

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

<pre>Geometry - Circle Summary
-------------------------------------
Radius:   @((new Circle(rad)).Radius)
PI:       @Circle.PI
Diameter: @((new Circle(rad))
Area:     @((new Circle(rad))</pre>

This would produce:

Geometry - Circle Summary
-------------------------------------
Radius:   837.58
PI:       3.14
Diameter: 1675.16
Area:     2202836.4050960005

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 of a Class

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:

@functions
{
    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:

@functions
{
    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:

@functions
{
    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:

@functions
{
    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:

@functions
{
    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:

@page
@model Valuable.Pages.ExerciseModel
@{
    Equation eq = new Equation(2, 3, 18);
}

@functions
{
    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(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;
        }
    }
}

<p>Equation: @eq.Create()</p>

<hr />

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

<p>Equation: @eq.Create()</p>

<hr />

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

<p>Equation: @eq.Create()</p>

This would produce:

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

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:

@functions
{
    class Employee
    {
    }

    class TimeSheet
    {
        private double timeWorked;
        private string filingStatus;

        public Employee Employee;
    }
}

Previous Copyright © 2001-2022, C# Key Monday 27 December 2021 Next