Fundamentals of Structures

Introduction

To store the values presented to it, a computer divides its memory in two parts. The heap is the section in which the objects from classes are stored. In previous lessons, we saw various examples of creating classes and creating objects from classes. Such objects are stored in the heap. We also saw that, to create an object and store it in the heap, we must use the new operator. To refer to an object stored in the heap, you must use its reference. This means that you don't need nor get the actual object. You only need its address in the computer memory.

The stack is the section of memory that stores small values such as natural numbers, symbols, or Boolean values. The actual values of such types are available, not simply their addresses. If you want, you can create a group of values of small types, called primitive data types. This is the role of a structure.

A structure, like a class, is a list of types used to describe an object. Unlike a class that is used for large and complex objects, a structure is used for small objects.

Creating a Structure

To create a structure, you use the same formula as for a class but use the struct keyword. Here is an example that starts a structure:

struct Integer
{
}

Like a class, the creation of a structure can start with an access level, usually the public or the internal keyword. Here is an example:

public struct Integer
{
}

Structures and Fields

Like a class, a structure can have fields. They are listed in the body of the structure. Here is an example:

struct Integer
{
    private int val;
}

Structures and Properties

A structure, like a class, can have properties. A property is created using the exact same rules and suggestions we saw for classes. Here is an example of a property with a complete definition:

struct Integer
{
    private int val;

    public int Value
    {
        get { return val; }
        set { val = value; }
    }
}

In the same way, a method can return a value of a primitive type. A method can use one or more parameters. A method can be overloaded with various versions that take different parameters. Here is an example:

public struct Road
{
    private string id;
    private double len;
    private string ending;
    private string beginning;

    public string Designation
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
        }
    }
   
    public double Distance
    {
        get { return len;  }
        set { len = value; }
    }
    public string Start
    {
        get { return beginning; }
        set { beginning = value; }
    }
    public string End
    {
        get { return ending; }
        set { ending = value; }
    }

    public double GetDistanceInKilometers()
    {
        return Distance * 1.6093;
    }
}

Structures and Constructors

A Default Constructor?

A structure, like a class, can have one or more constructors. We saw that, if you don't create any constructor in a class, the compiler will create a default constructor for your class, that is, a constructor that doesn't use any parameter. We also saw that, if you create at least one constructor in a class and that single constructor uses at least one parameter, or all constructors of the class have at least one parameter, the default constructor would not be available anymore. In that case, if you still want a default constructor, you must explicitly create a constructor that doesn't use a parameter.

When it comes to a structure, the compiler always creates a default constructor for you and that constructor cannot be hidden. As a result, you are not allowed to create a default constrcutor in a structure.

Creating Constructors in a Structure

If you decide to create a constructor in a structure, that constructor must have at least one parameter. Other than that rule, the constructors of a structure follow the same rules and suggestions of constructors of a class. For example, a structure can use one constructor that uses one or more parameters Here is an example:

struct Integer
{
    private int val;

    public Integer(int number)
    {
        val = number;
    }
    
    public int Value
    {
        get { return val; }
        set { val = value; }
    }

    public void Read()
    {
    }
}

A constructor can be overloaded with various versions that use different parameters. Here is an example:

struct Integer
{
    private int val;

    public Integer(int number)
    {
        val = number;
    }
    
    public Integer(string number)
    {
        val = int.Parse(number);
    }
    
    public Integer(int number, int maximumSize)
    {
        val = number;
        maximumSize = 1;
    }
    
    public int Value
    {
        get { return val; }
        set { val = value; }
    }

    public void Read()
    {
    }
}

Creating an Object from a Structure

To use a structure, you can declare a variable of it. Initialize the variable as done for a class, using the new operator. Remember that a structure always has a default constructor. Therefore, if you don't have an initial value, initialize the variable with the default constructor. Here is an example:

public struct Integer
{
    private int val;

    public Integer(int number)
    {
        val = number;
    }

    public Integer(string number)
    {
        val = int.Parse(number);
    }

    public Integer(int number, int maximumSize)
    {
        val = number;
        maximumSize = 1;
    }

    public int Value
    {
        get { return val; }
        set { val = value; }
    }

    public void Read()
    {
    }
}

public class Exercise
{
    public void Create()
    {
        Integer itg = new Integer();
    }
}

You can also initialize the variable with a constructor that uses one or more parameters. Here is an example:

public struct Integer
{
    private int val;

    public Integer(int number)
    {
        val = number;
    }
}

public class Exercise
{
    public static void Main()
    {
        Integer itg = new Integer(1257);
    }
}

As done for variables of the other types and as seen for classes, to declare a variable for a structure, you can use the var keyword.

Accessing the Members of a Structure

After declaring a variable of a structure, you can use the object the same way you would use a class. You can access its members (fields, properties, and methods) using the period operator. Here is an example:

public struct Integer
{
    private int val;

    public Integer(int number)
    {
        val = number;
    }

    public int Value
    {
        get { return val; }
        set { val = value; }
    }
}

public class Exercise
{
    public void Create()
    {
        Integer itg = new Integer();

    	itg.Value = 1500;
    }
}

Topics on Structures

Fields and Constructors

We have seen that every new structure automatically has a default constructor and you are not allowed to explicitly create a default constructor. If you do, you would receive an error.

As mentioned previously, in a structure, you can create one or more fields, as (a) local variable(s). One of the differences between a class and structure is that, if you create a field in a structure, you must initialize that field in a constructor of the structure (if you create a field in a class, you are not required to initialize that field). Here is an example:

public struct Sit
{
    int _size;

    public Sit(int size) { this._size = size; }
}

Structures and Inheritance

A structure is sealed from inheritance. This means that you cannot create a class or a structure that is based on, or is derived from, a structure.

Structures and Enumerations

An enumeration can be involved with a structure. The typical way is to create a field that is of an enumeration type. Here is an example:

public enum Category { Highway, Interstate }

public struct Road
{
    Category cat;
}

In the same way, you can create a property of the type of an enumeration. You can then use the property like we learned for classes.

Expression-Bodied

We already know that the C# language provides the => operator that can be used to simplify the code of a function/method or the code of a property. This operator is used in a structure the same way it is used in a class. Here are examples:

public struct Road
{
    private string id;
    private double len;
    Category cat;
    private string ending;
    private string beginning;

    public string Designation
    {
        get => id;
        set => id = value;
    }

    public Category RoadType
    {
        get => cat;
        set => cat = value;
    }

    public double Distance
    {
        get => len;
        set => len = value;
    }
    
    public string Start
    {
        get => beginning;
        set => beginning = value;
    }

    public string End
    {
        get => ending;
        set => ending = value;
    }

    public double GetDistanceInKilometers() => Distance * 1.6093;
}

Automatic Properties

The properties of a structure can be created as automatic ones. Those properties are created and follow the same rules we applied to those of classes. Here are examples:

public struct Road
{
    public string Designation { get; set; }
    public Category RoadType { get; set; }
    public double Distance{ get; set; }
    public string Start { get; set; }
    public string End { get; set; }

    public double GetDistanceInKilometers() => Distance * 1.6093;
}

A Property of a Structure Type

Once a structure exists, you can use it as a type. For example, you can create a property that is a structure type. The rules are the same we reviewed for creating a property of a class. Here are examples:

public enum Category
{
    Regular,
    StateHighway,
    USHighway,
    Interstate,
    CapitalBeltway
}

public struct Road
{
    private string id;
    private double len;
    private Category cat;
    private string ending;
    private string beginning;

    public Road(string identification)
    {
        len = 0.00;
        ending = "";
        beginning = "";
        id = identification;
        cat = Category.Regular;
    }

    public Road(string identification, Category type, double length)
    {
        cat = type;
        ending = "";
        len = length;
        beginning = "";
        id = identification;
    }

    public string Designation
    {
        get
	{
            return id;
        }
        set
        {
            id = value;
        }
    }

    public Category RoadType
    {
        get { return cat; }
        set { cat = value; }
    }
   
    public double Distance
    {
        get { return len;  }
        set { len = value; }
    }
    public string Start
    {
        get { return beginning; }
        set { beginning = value; }
    }
    public string End
    {
        get { return ending; }
        set { ending = value; }
    }

    public double GetDistanceInKilometers()
    {
        return len * 1.6093;
    }
}

public class Intersection
{
    public Road Road1 { get; set; }
    public Road Road2 { get; set; }
    public string InOrNear { get; set; }

    public Intersection()
    {
    }

    public Intersection(Road one, Road two, string position)
    {
        Road1 = one;
        Road2 = two;
        InOrNear = position;
    }
}

After creating the property, you can use it as you see fit.

Returning a Structure From a Function or Method

Like a regular data type or a class, a structure can serve as the return type of a function or a method. The rules are more related to those of a class. When creating the method, type the name of the structure on the left side of the name of the method. In the body of the method, implement the desired behavior. Before exiting the method, make sure you return a valid value that is of the type of the structure.

When a method returns a value of the type of a structure, you can assign the method call to a variable of the type of the structure.

Passing a Structural Object as Argument

Like a regular data type, a structure can be used as the type of a parameter of a method. The argument is primarily passed as done for a class. After passing the argument, in the body of the method, you can access the public members of the structure, using the period operator.

Passing a Structural Object by Reference

When you pass a structure to a method, it is referred to as passing by value. A copy of the value of the structure is passed to the method. If the method modifies the argument, the original variable would stay intact. If you want the method to modify the value of the structure, you can pass the argument by reference. You can do this using the (rules of the) ref and the out keywords.


Previous Copyright © 2001-2022, FunctionX Friday 26 November 2021 Next