Fundamentals of Staticity

Introduction

Consider a class as follows:

@functions{
    public class Chemistry
    {
    }
}

If you have a class, to access it outside its body, you can declare a variable of it as we have done so far. In the same way, you can declare various instances of the same class. Here are examples:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    // A variable of the class
    Chemistry chem = new Chemistry();

	// Another variable of the class
    Chemistry item = new Chemistry();
}

@functions{
    public class Chemistry
    {
        
    }
}

A variable you have declared of a class is also called an instance of the class. Each instance gives you access to the members of the class but each instance holds the particular values of the members of its instance. All the member variables and methods of classes we have used so far are referred to as instance members because, in order to access them, you must have an instance of a class declared in another class in which you want to access them.

In your application, you can declare a variable and refer to it regardless of which instance of an object you are using. Such a variable is referred to as static.

A Static Field

To declare a member variable of a class as static, that is, to create a static field, type the static keyword on its left. Here is an example:

@functions{
    public class Chemistry
    {
        static string Category;
    }
}

In the same way, you can create as many static fields as you want. As we saw in previous lessons, you can control access to a field using a modifier (private, public, internal or protected). If you apply the modifier, the static keyword can be written before or after it, as long as it appears before the data type. Here are examples:

@functions{
    public class Chemistry
    {
        public static int Period;
        static public int Group;
    }
}

To access a static variable, you must "qualify" it where you want to use it. Qualifying a member means you must specify its class, followed by a period, and followed by the static field. Here are examples:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Car.make = "Ford";
    Car.model = "Escort";
}

@functions{
    public class Car
    {
        public static string make;
        static public string model;
    }
}

<pre>Vehicle Registration
---------------------
Make:  @Car.make
Model: @Car.model
======================</pre>

This would produce:

Vehicle Registration
---------------------
Make:  Ford
Model: Escort
======================

This means that when a field has been created as static, you don't need an instance of the class to access that member variable outside of the class. Based on this, if you declare all members of a class as static, you don't need to declare a variable of their class in order to access them.

In your class, you can create a combination of static and non-static fields if you judge it necessary. You just have to remember that, to access a static variable, you don't create an instance of the class. To access a non-static variable, you must declare a variable for the class. Here is an example:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Car cr    = new();
    Car.make  = "Toyota";
    Car.model = "Camry";
    cr.doors  = 4;
}

@functions{
    public class Car
    {
        public static string make;
        static public string model;
        public int           doors;
    }
}

<pre>Vehicle Registration
---------------------
Make:  @Car.make
Model: @Car.model
Doors: @cr.doors
======================</pre>

This would produce:

Vehicle Registration
---------------------
Make:  Toyota
Model: Camry
Doors: 4
======================

You can create a method in a class. That method can directly access static and non-static members by their names. From a local method, a static field can be accessed either by its name or by qualifying it. Here are examples:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Residence res = new Residence();
    
    res.Present();
}

@functions{
    class Residence
    {
        public static int Bedrooms;
        static public double Bathrooms;
        public double MarketValue;
        public string ConstructionStatus;
        
        public void Present()
        {
            Bedrooms = 5;
            Residence.Bathrooms = 3.50;
            ConstructionStatus = "Needs Renovation";
            MarketValue = 545_825;
        }
    }
}

<pre>   ==//== Altair Realtors ==//==
---------------------------------------
Number of Bedrooms:   @Residence.Bedrooms
Number of Bathrooms:  @Residence.Bathrooms
Construction Status:  @res.ConstructionStatus
Market Value:         @res.MarketValue
=======================================</pre>

This would produce:

   ==//== Altair Realtors ==//==
---------------------------------------
Number of Bedrooms:   5
Number of Bathrooms:  3.5
Construction Status:  Needs Renovation
Market Value:         545825
=======================================

Introduction to Static Properties

A property can be made static. One option is to create the property in a normal class. Then write static on the left side of the data type of the property. If you are creating a property that controls the value of a property, the corresponding field must also be static. Here is an example:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Square sqr = new Square();

    Square.Side = 248.77;
}

@functions{
    public class Square
    {
        private static double s;

        public static double Side
        {
            get { return s; }
            set { s = value; }
        }

        static public double Perimeter
        {
            get
            {
                return s * 4;
            }
        }

        public double Area { get { return s * s; } }
    }
}

<pre>===========================
Square Values
---------------------------
Area:      @sqr.Area
Perimeter: @Square.Perimeter
===========================</pre>

This would produce:

===========================
Square Values
---------------------------
Area:      61886.5129
Perimeter: 995.08
===========================

A Static Enumerated Property

A property created from an enumeration can be created as a static property. To do this, on the left side of the type of the property, type the static keyword. Here are examples:

@functions{
    public enum Alignment
    {
        FarLeft, Left, CenterLeft,
        Center,
        CenterRight, Right, FarRight
    }

    public class PoliticalParty
    {
        private static Alignment align;

        static public Alignment Affiliation
        {
            get
            {
                return align;
            }

            set
            {
                align = value;
            }
        }

        public static Alignment Policy { get; set; }
    }
}

Static Methods

Introduction

Like a field, a method of a class can be made static. Such a method can access any member of the class but it depends on how the member was declared. Remember that you can have static or non-static members of a class.

Creating a Static Method

To define a method as static, type the static keyword to its left. Here is an example:

@functions{
    public class Chemistry
    {
        static void Display()
        {
        }
    }
}

A static method can also use an access modifier. You can write the access modifier before or after the static keyword. Here is an example:

@functions{
    public class Chemistry
    {
        public static void Display()
        {
        }
    }
}

As mentioned for a static field, using a static method depends on where it is being accessed. To access a static member from a static method of the same class, you can just use the name of the static member. Here is an example:

@functions{
    public class Chemistry
    {
        static private string Category;

        private static void Categorize()
        {
            Category = "Alkali Metal";
        }
    }
}

You can also qualify the member by typing the name of the class, followed by a period, followed by the member. Here is an example:

@functions{
    public class Chemistry
    {
        static private string Category;

        private static void Categorize()
        {
            Chemistry.Category = "Alkali Metal";
        }
    }
}

To access a non-static member from a static method of the same class, you must declare a variable of the class and use it. Here is an example:

@functions{
    public class Residence
    {
        public static int Bedrooms;
        static public double Bathrooms;
        public double MarketValue;
        public string ConstructionStatus;

        static public void Create()
        {
            Residence res = new Residence();

            Bedrooms = 5;
            Residence.Bathrooms = 3.50;
            res.ConstructionStatus = "Needs Renovation";
            res.MarketValue = 545_825;
        }
    }
}

The Type of a Field as its Own Class

We already know that, in a class, you can create a field whose type is its own class. We also saw that you can initialize such a field in the body of the class. Such a field usually doesn't modify any member of its class. In this case, when accessing the field outside its class, you don't need an object of the class. As a result, you can/should make the field static. Here are examples:

namespace Chemistry.Models
{
    public enum Phase { Gas, Liquid, Solid, Unknown }

    public class Element
    {
        internal string ElementName  { get; set; }
        internal string Symbol       { get; set; }
        internal int    AtomicNumber { get; set; }
        internal double AtomicWeight { get; set; }
        internal Phase  Phase        { get; set; }

        public Element()                 { }
        public Element(string symbol) => Symbol = symbol;
        public Element(int number)    => AtomicNumber = number;

        public Element(int number, string symbol, string name, double mass, Phase phase)
        {
            ElementName  = name;
            AtomicWeight = mass;
            Phase        = phase;
            Symbol       = symbol;
            AtomicNumber = number;
        }

        public static Element Ar = new Element(18, "Ar", "Argon", 39.948, Phase.Gas);
        public static Element K = new Element(phase: Phase.Solid, number: 19, symbol: "K", name: "Potassium", mass: 39.098);
        public static Element Ca = new(20, "Ca", "Calcium", 40.078, Phase.Solid);
        public static Element Sc = new(number: 21, symbol: "Sc", phase: Phase.Solid, name: "Scandium", mass: 44.956);
        public static Element Ti = new(name: "Titanium", number: 22, symbol: "Ti", mass: 47.867, phase: Phase.Solid);
        public static Element V = new Element()
        {
            AtomicNumber = 23,
            Symbol = "V",
            AtomicWeight = 50.942,
            ElementName = "Vanadium"
        };
    }
}

Static Classes

Introduction

Like a variable or a method, a class can be made static. A static class:

Creating a Static Class

To create a static class, precede the class keyword with the static keyword. Based on the above two rules, all members of a static class must be made static. Here is an example:

namespace CountriesStatistics.Models
{
    public static class Region
    {
        public static string Name;
        public static string States;
    }
}

Accessing a Static Class

To use a static class, don't declare a variable of the class; that is, don't create an instance of the class. To access any member of the class, type the name of the class, a period, and the desired member. Here are examples:

namespace CountriesStatistics.Models
{
    public static class Region
    {
        public static string Name;
        public static string States;
    }

    public class Statistics
    {
        public void Create()
        {
            Region.Name = "New England";
            Region.States = "Connecticut, Maine, Massachusetts, New Hampshire, Rhode Island, and Vermont";

            string str = Region.Name;
            string stt = Region.States;
        }
    }
}

In the above example, we created both the static and the non-static class in the same document. Of course, you can create each class in its own file. Here is an example of a file named Administration.cs that contains a static class:

namespace PracticalLearning.Models
{
    public static class Management
    {
        public static string Category;
        public static int WorkCode;
    }
}

Using a Static Class

As another technique to access a static class, in the top section of the document where you want the static class, type using static followed by the name of the static class and a semicolon. Then, in the document, you can simply type the name of the member you want to access. Here is an example:

using static Management;

public class Workload
{
    public void Create()
    {
        Category = "Full-Time";
        string emplName = "Esther Garland";
        WorkCode = 927004;

        string cat = Category;
        string wc  = WorkCode;
    }
}

Static Constructors

Like a normal method, a constructor can be made static. There are rules you must follow. If you want to use a static constructor, you must explicitly create it (the compiler doesn't create a static constructor for you).

The static constructor must become the default constructor. That is, you must create a constructor that doesn't use any parameter. Here is an example:

namespace PracticalLearning.Models
{
    public class Person
    {
        public string firstName;

        static Person()
        {
        }
    }
}

If you create a static constructor, you cannot directly access the non-static fields of the class:

Static Constructor

You can still access any field of the class as you see fit. Here are examples:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Person pers = new();
    
    pers.firstName = "Gertrude";
}

@functions{
    public class Person
    {
        public string firstName;

        static Person()
        {
            
        }
    }
}

<pre>===========================
Employee Information
---------------------------
Empl Name: @pers.firstName
===========================</pre>

To use a static constructor, you have various options. To initialize a field in the static constructor, you can declare a variable of the class and access the member variable. Here is an example:

namespace PracticalLearning.Models
{
    public class Person
    {
        public string firstName;

        static Person()
        {
            Person pers = new Person();

            pers.firstName = "Gertrude";
        }
    }
}

In reality, one of the reasons for using a static constructor is to initialize the static fields of the class or perform any action that would be shared by all instances of the class. Therefore, another option to use a static constructor is to initialize the static fields. After doing this, when accessing the initialized static field(s), it(they) would hold the value(s) you gave it(them). Here is an example:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Person.firstName = "Gertrude";
}

@functions{
    public class Person
    {
        public static string firstName;
        
        static Person()
        {
            firstName = "Gertrude";
        }
    }
}

<pre>===========================
Employee Information
---------------------------
Empl Name: @Person.firstName
===========================</pre>

Because the constructor is static, you cannot access it by declaring a variable of the class.

Another rule to observe with a static constructor is that you must not add an access modifier to it. The following will result in an error:

@functions{
    public class Person
    {
        public static Person()
        {
        }
    }
}

As mentioned already, you can create a class that uses a combination of a static constructor and one or more other (non-static) constructors. Here is an example:

@functions{
    public class Person
    {
        static Person()
        {
        }

        public Person(string first, string last)
        {
        }
    }
}

If you create such a class and if you want to declare a variable for it, the default constructor doesn't exist or is not available. If you want to declare a variable, you must use a constructor that uses a parameter. Here is an example:

@page
@model PracticalLearning.Pages.StaticityModel
@{
    Person pers = new Person("Gertrude", "Monay");
}

@functions{
    public class Person
    {
        public string firstName;
        public string lastName;

        static Person()
        {
        }

        public Person(string first, string last)
        {
            firstName = first;
            lastName = last;
        }
    }
}

<pre>===========================
Employee Information
---------------------------
Empl Name: @pers.firstName @pers.lastName
===========================</pre>

This would produce:

===========================
Employee Information
---------------------------
Empl Name: Gertrude Monay
===========================

Static Classes and Namespaces

Introduction

When creating a static class, you can include it in a namespace. Here is an example:

namespace BusinessManagement
{
    static class LoanApplicant
    {
        public static long AccountNumber = 402_924_759;
        public static string FullName = "Joseph Nyate";
    }
}

Using a Static Class of a Namespace

If the code where you want to access a static class is in the same namespace as the static class, you can use the class by its name. Here is an example:

using static System.Console;

public class Exercise
{
    static void Main()
    {
        WriteLine("Loan Application");
        Write("Account #: ");
        WriteLine(LoanApplicant.AccountNumber);
        Write("Applicant Name: ");
        WriteLine(LoanApplicant.FullName);
    }
}

namespace BusinessManagement
{
    static class LoanApplicant
    {
        public static long AccountNumber = 402_924_759;
        public static string FullName = "Joseph Nyate";
    }
}

As we have learned, if the class was created in a namespace different from the area where you want to use it, one option is to fully qualify the name of the class.

Another option is to first add a using line that includes the static class's namespace, then use the name of the class.

As another option, in the top section of the code, type using static followed by the name of the namespace, a period, and the name of the class. Then, in the code, directly access any of the members of the static class.

this Object

Introduction

If a class contains fields and methods, the (non-static) field members are automatically available to all method(s) of the class, even fields that are private. When working inside a class, such as accessing a field or a method of the class from another member of the same class, to let you indicate that you are referring to the class or to a member of the same class, the C# language provides a special object named this (in C++, it is called a pointer). Then add the period operator.

Accessing a Member of this Class

While working from within a class, to access one of its non-static members, you can type this followed by a period and the desired member. Here are examples:

namespace Geometry.Models
{
    public class Circle
    {
        private double radius;

        public readonly double PI = 3.14159;

        public double CalculateDiameter()
        {
            return this.radius * 2;
        }

        public double CalculateCircumference()
        {
            return this.CalculateDiameter() * this.PI;
        }

        public double CalculateArea()
        {
            return this.radius * this.radius * this.PI;
        }
    }
}

Because the this keyword indicates that you are using a member from within the class, a method can use a parameter that has the same name as a member of the class and, by using the this keyword, you would not have any name conflict. Here is an example:

namespace PracticalLearning.Models
{
    public class Circle
    {
        private double radius;

        public readonly double PI = 3.14159;

        public Circle(double radius)
        {
            // In "this.radius", the radius is the one in the class
            // In "radius", the radius is the parameter of the method
            this.radius = radius;
        }
    }
}

As you might have realized from the above code and from previous lessons, the this keyword is mostly optional. Other than that, the public members can still be accessed outside the class.

Characteristics of this Object

When using this, you can access any member of a class within any method or property of the same class. There are rules you must observe when using this:

this Method Returns an Object of its Class

A method of a class can be made to return an object of its class. We saw this feature in a previous section. An alternative is to return the this object. Here is an example:

namespace PeriodicTable.Models
{
    public class Chemistry
    {
        public string Element;
        public string Symbol;
        public int AtomicNumber;
        public double AtomicWeight;

        public Chemistry Initialize()
        {
            Symbol = "N";
            AtomicNumber = 7;
            Element = "Nitrogen";
            AtomicWeight = 14.007;

            return this;
        }
    }
}

Class Nesting

Introduction

A class can be created inside of another class. A class created inside of another is referred to as nested.

Nesting a Class

To nest a class, click inside an existing class and type the necessary code for the new class, starting with the class keyword followed by a name and {}. If you are using Microsoft Visual Studio, select the whole class. Right-click the selection and click Surround With... In the list, double-click class. Here is an example of a class called Inside that is nested in a class called Outside:

public class Outside
{
    public class Inside
    {
    }
}

In the same way, you can nest as many classes as you wish in another class and you can nest as many classes as you want inside of other nested classes if you judge it necessary. Just as you would manage any other class, you exercise control a nested class. For example, you can create all necessary fields and/or methods in the nested class or in the nesting class. When you create one class inside of another, there is no special programmatic relationship between both classes: just because a class is nested does not mean that the nested class has immediate access to the members of the nesting class. They are two different classes and they can be used separately.

Accessing a Nested Class

The name of a nested class is not "visible" outside of the nesting class. To access a nested class outside of the nesting class, you must qualify the name of the nested class anywhere you want to use it. For example, if you want to declare an Inside variable somewhere in the program but outside of Outside, you must qualify its name. Here is an example:

public class Outside
{
    public class Inside
    {
    	public Inside()
	   {
	    
	   }
    }

    public Outside()
    {
	
    }
}

Outside recto = new Outside();
Outside.Inside ins = new Outside.Inside();

Because there is no programmatically privileged relationship between a nested class and its "container" class, if you want to access the nested class in the nesting class, you can use its static members. In other words, if you want, you can create static members (fields and/or methods) of the nested class you want to access in the nesting class.


Previous Copyright © 2001-2022, C# Key Sunday 14 November 2021 Next