Introduction to Structures
Introduction to Structures
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 (this is not a strict rule but a "best practice"; therefore, use a structure for a small object and consequently, don't use a structure for large objects).
Practical Learning: Introducing Structures
namespace RoadSystemDatabase1
{
}
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
{
}
Practical Learning: Creating a Structure
namespace RoadSystemDatabase1
{
internal struct Road
{
}
}
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;
}
Practical Learning: Adding a Field to a Structure
namespace RoadSystemDatabase1
{
internal struct Road
{
private string? id;
private double len;
private string? ending;
private string? beginning;
}
}
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; }
}
}
Practical Learning: Creating Properties in a Structure
internal 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; }
}
}
Structures and Methods
Like a class, a structure can have methods. A structure supports all concepts we reviewed for methods of classes. A method of a structure can be of type void. Here is an example:
struct Integer
{
private int val;
public int Value
{
get { return val; }
set { val = value; }
}
public void Read()
{
}
}
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.
Practical Learning: Adding a Method to a Structure
namespace RoadSystemDatabase1
{
internal 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
As seen with a class, a default constructor is a method that holds the same name as the class and doesn't return a value. Like a class, a structure can have a default constructor. Here is an example:
internal struct Toilet
{
public Toilet()
{
}
}
One of the differences between a class and a structure is that, if a struture has one or more fields and/or properties, if you create a default constructor in a structure, you must initialize everyone of the fields in the default constructor.
Practical Learning: Adding a Method to a Structure
namespace RoadSystemDatabase1
{
internal struct Road
{
private string? id;
private double len;
private string? ending;
private string? beginning;
public Road()
{
len = 0.00;
id = default;
ending = default;
beginning = default;
}
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;
}
}
}
Parameterized Constructors
As seen with a class, you can create a constructor that uses one or more parameters in a structure. The constructors of a structure follow the same rules and suggestions of constructors of a class. 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() { } }
Practical Learning: Adding Constructors to a Structure
namespace RoadSystemDatabase1
{
internal struct Road
{
private string? id;
private double len;
private string? ending;
private string? beginning;
public Road()
{
len = 0.00;
id = default;
ending = default;
beginning = default;
}
public Road(string identification)
{
len = default;
ending = default;
beginning = default;
id = identification;
}
public Road(string identification, double length)
{
ending = default;
len = length;
beginning = default;
id = identification;
}
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 len * 1.6093;
}
}
}
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:
internal 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:
internal struct Integer
{
private int val;
public Integer(int number)
{
val = number;
}
}
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:
internal 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;
}
}
Practical Learning: Accessing a Structure
using static System.Console;
using RoadSystemDatabase1;
Road rd = new Road();
rd.Designation = "I-83";
rd.Distance = 85.3;
rd.Start = "East Fayette Street / North President Street / Fallsway in Baltimore, MD";
rd.End = "I-81 / US 322 / Capital Beltway in Harrisburg, PA";
WriteLine("Road System Database");
WriteLine("=====================================================================================");
WriteLine("Road Name: {0}", rd.Designation);
WriteLine("Length: {0} miles, {1} kilometers", rd.Distance, rd.GetDistanceInKilometers());
WriteLine("Start: {0}", rd.Start);
WriteLine("End: {0}", rd.End);
WriteLine("=====================================================================================");
Road System Database ===================================================================================== Road Name: I-83 Length: 85.3 miles, 137.27329 kilometers Start: East Fayette Street / North President Street / Fallsway in Baltimore, MD End: I-81 / US 322 / Capital Beltway in Harrisburg, PA ===================================================================================== Press any key to close this window . . .
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:
internal 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 } internal 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.
Practical Learning: Using an Enumeration
namespace RoadSystemDatabase1 { internal enum Category { Regular, StateHighway, USHighway, Interstate, Beltway } }
namespace RoadSystemDatabase1 { internal struct Road { Category cat; private string? id; private double len; private string? ending; private string? beginning; public Road() { len = 0.00; id = default; ending = default; beginning = default; cat = Category.Regular; } public Road(string identification) { len = default; ending = default; beginning = default; id = identification; cat = Category.Regular; } public Road(string identification, double length) { ending = default; len = length; beginning = default; id = identification; cat = Category.Regular; } 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 Distance * 1.6093; } } }
using static System.Console; using RoadSystemDatabase1 Road rd = new Road(); rd.Designation = "I-83"; // Roads Categories: Regular, Beltway, Interstate, US Highway, State Highway rd.RoadType = Category.Interstate; rd.Distance = 85.3; rd.End = "I-81 / US 322 / Capital Beltway in Harrisburg, PA"; rd.Start = "East Fayette Street / North President Street / Fallsway in Baltimore, MD"; WriteLine("Road System Database"); WriteLine("====================================================================================="); WriteLine("Road Name: {0}", rd.Designation); WriteLine("Road Type: {0}", rd.RoadType); WriteLine("Start: {0}", rd.Start); WriteLine("End: {0}", rd.End); WriteLine("Length: {0} miles, {1} kilometers", rd.Distance, rd.GetDistanceInKilometers()); WriteLine("=====================================================================================");
Road System Database ===================================================================================== Road Name: I-83 Start: East Fayette Street / North President Street / Fallsway in Baltimore, MD End: I-81 / US 322 / Capital Beltway in Harrisburg, PA Road Type: Interstate Length: 85.3 miles, 137.27329 kilometers ===================================================================================== Press any key to close this window . . .
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.
Practical Learning: Creating Expression-Bodied Propertie and Methods
namespace RoadSystemDatabase1 { internal struct Road { private Category cat; private string? id; private double len; private string? ending; private string? beginning; public Road() { len = 0.00; id = default; ending = default; beginning = default; cat = Category.Regular; } public Road(string identification) { len = default; ending = default; beginning = default; id = identification; cat = Category.Regular; } public Road(string identification, double length) { ending = default; len = length; beginning = default; id = identification; cat = Category.Regular; } 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:
namespace RoadSystemDatabase
{
internal 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
}
internal 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.
Practical Learning: Using a Structure Object
using static System.Console; using RoadSystemDatabase; // Returning a structural object from a function Road Create() { Road rd = new Road(); rd.Distance = 232.406; rd.Designation = "US 36"; rd.RoadType = Category.USHighway; rd.End = "US-36 on CO-KS border"; rd.Start = "Deer Ridge - US 34"; return rd; } // Passing a structural object as argument void Show(object obj) { if (obj is null) return; Road rd = (Road)obj; WriteLine("Road System Database"); WriteLine("============================================"); WriteLine("Road Name: {0}", rd.Designation); WriteLine("Road Type: {0}", rd.RoadType); WriteLine("--------------------------------------------"); WriteLine("Start: {0}", rd.Start); WriteLine("End: {0}", rd.End); WriteLine("Length: {0:N} miles ({1:N} kilometers)", rd.Distance, rd.GetDistanceInKilometers()); WriteLine("============================================"); } Road rd = Create(); Show(rd);
Road System Database ============================================ Road Name: US 36 Road Type: USHighway -------------------------------------------- Start: Deer Ridge - US 34 End: US-36 on CO-KS border Length: 232.41 miles (374.01 kilometers) ============================================ Press any key to close this window . . .
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.
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2001-2023, FunctionX | Friday 26 November 2021 | Next |
|