Introduction to Records
Introduction to Records
Fundamentals of Records
Introduction
In previous lessons, we were introduced to classes as a way to create a layout for objects. We saw other options to create objects, such as tuples and structures. Like those options, a record is a technique to combine characteristics that describe an object. There are many similarities between classes, structures, and records. We are going to review many of those issues before getting to the differences between classes and structures on one hand, and records on the other hand.
Practical Learning: Introducing Records
body { } .bold { font-weight: bold; } .text-right { text-align: right; } .delimiter { margin: auto; width: 650px; } .top-bar { border-bottom: 6px solid blue; background-color: #093b12 !important; } .navbar-light .navbar-brand { color: white; } .navbar-light .navbar-brand:hover { color: yellow; } .navbar-light .navbar-brand:focus { color: khaki; } .navbar-light .navbar-brand { font-family: Georgia, Garamond, 'Times New Roman', serif; } .nav-link { font-family: Georgia, Garamond, 'Times New Roman', serif; } .common-font { font-family: Georgia, Garamond, 'Times New Roman', serif; }
To create a record, you use a keyword named record. The primary formula to follow is:
access-level record name {}
As always when you create a layout for an action or an object, you can start with some options that sometimes are not required. The primary option you can apply is an access level. In many cases, an access level is not required but if you decide to use one, apply the public or internal to your record. The option(s) is (are) followed by the record keyword. As always, you must name the layout you are creating. The name of a record follows the rules of names of classes, structures, enumerations, and namespaces. As seen with those objects, a record must have a body, which starts with an opening curly bracket { and ends with a closing curly bracket }.
Practical Learning: Creating a Record
namespace PayrollPreparation3.Models { internal record Employee { } }
Accessing a Record
When you create a record, you are simply providing a skeleton for an eventual object. To get an actual object, declare a variable of the record. You can use the name of the record as type. This is followed by a name. The name of the object follows the rules of names of variables. Add the assignment operator. A record is a reference type. As a result, you must use the new operator when creating the object. Add the name of the record and parentheses. Here is an example:
@{
DayWork it = new DayWork();
}
@functions{
internal record DayWork
{
}
}
As seen with classes and structures, when initializing the object of a record, if you are creating it using the name of the record, you can omit that name after the new operator, but the name of the record is required if you are using the var or the dynamic keyword to create the object. Here are examples:
@{ // A classi way to create an object DayWork it = new DayWork(); // An object from the name of the record and created using the "new" operator Canoe fun = new(); // A variable declared using the "var" keyword var leisure = new Canoe(); // A "dynamic" object dynamic summer = new Canoe(); } @functions{ internal record Canoe { } }
A Field in a Record
When creating a record, you should fill it with some useful members. As seen with classes and structures, the simplest thing you can do in a record is to declare a variable of a primitive type. Such a variable is also called a field. Here is an example:
public record Employee { string nbr; }
You can then use that field. Before doing that, you should apply an appropriate access level. As a reminder, if you apply the private level, the field can be accessed only by members of the same record. If you want the field to be accessed outside the record, you should apply the public or the internal levels.
Introduction to the Properties of a Record
A property is a characteristic that allows a record to communicate or exchange values with other objects. As seen with classes and structures, all options to create properties are available in a record. As a reminder, if you had added a private field to a record, you can create a complete property for it, with a get and a set clauses. Here is an example:
public record Employee { int nbr; public int EmployeeNumber { get { return nbr; } set { nbr = value; } } }
After creating a property, you can access it the same way you would access a property of a class or structure. Here is an example:
@page @model Exercises.Pages.ExerciseModel @{ Employee staff = new Employee(); staff.EmployeeNumber = 428_350; } @functions{ public record Employee { int nbr; public int EmployeeNumber { get { return nbr; } set { nbr = value; } } } } <pre>Employee #: @staff.EmployeeNumber</pre>
This would produce:
Employee #: 428350
In the same way, you can use a conditional statement in a clause to accept a value, change a value, or reject a value. Here is an example:
@page @model Exercises.Pages.ExerciseModel @{ Employee staff = new Employee(); staff.EmployeeNumber = 428_350; staff.HourlySalary = 8.95; } @functions{ public record Employee { int nbr; double sal; public int EmployeeNumber { get { return nbr; } set { nbr = value; } } internal double HourlySalary { get { if (sal <= 10.00) return 15.55; else return sal; } set { sal = value; } } } } <pre>Employee #: @staff.EmployeeNumber); Hourly Salary: @staff.HourlySalary<pre>
This would produce:
Employee #: 428350 Hourly Salary: 15.55
In the same way, you can create one or more automatic properties in a record. Here is an example:
@{
DayWork it = new DayWork();
}
@functions{
internal record DayWork
{
public float TimeWorked { get; set; }
}
}
An Enumerated Property
As seen with structures and classes, a field of a record can be an enumerated type. Here is an example:
public enum FilingStatus { Single, Married, Unknown } public record Employee { FilingStatus category; }
In the same way, you can create a property of an enumeration type. Here is an example:
public enum FilingStatus { Single, Married, Unknown }
public record Employee
{
private FilingStatus category;
public FilingStatus FilingStatus
{
get
{
return category;
}
set
{
category = value;
}
}
}
Of course, you can create the property as an automatic one.
The Methods of a Record
Like a class or a structure, a record can have methods. You create the method exactly the same way you would create a method in a class or structure. Here is an example:
public enum FilingStatus { Single, Married, Unknown }
public record Employee
{
private FilingStatus category;
public FilingStatus FilingStatus
{
get
{
return category;
}
set
{
category = value;
}
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string GetFullName()
{
if (LastName == "")
throw new System.Exception("The last name is required for each employee.");
return FirstName + " " + LastName;
}
}
Everything else we reviewed for methods is available for records. For example, you can overload a method by passing different arguments to methods that use the same name. Here are examples:
public enum WorkCategory { Employee, Manager, Contractor, Seasonal, Unknown } public record StoreItem { public string PasswordManagement { get; set; } public string HiringSupervision { get; set; } public string Description { get; set; } // A method with a Boolean parameter public void Validate(bool isvalid) { if(isvalid) PasswordManagement = "Can Change Account Password"; else PasswordManagement = "Regular Employee"; } // A method with an enumerated parameter public void Validate(WorkCategory level) { if (level == WorkCategory.Manager) HiringSupervision = "Can Approve Hiring"; else HiringSupervision = "Regular Employee"; } // A method with two parameters public void Validate(int type, WorkCategory level) { switch (type) { case 2 when level == WorkCategory.Contractor: Description = "The job is a contract position on a temporary basis."; break; case 1 when level == WorkCategory.Seasonal: Description = "This is a full-time seasonal employee hired when season is at high pick."; break; case 3 when level == WorkCategory.Employee: Description = "The employment is be determined."; break; case 1 when level == WorkCategory.Manager: Description = "This is a managerial position with corporate credit cards."; break; case 2 when level == WorkCategory.Employee: Description = "This is a part-time employment position but put a regular payroll."; break; } } }
Records and Functions
Returning a Record
Once you have created a record, it becomes a regular type. You can involve it with a function. For example, you can create a function that returns a record. To start, create a function or method whose return type is an existing record. In the body of the function, process the values any way you like. Before the closing curly bracket of the function, you must return an object that holds a record object. Here is an example:
@{ Employee Create() { int number = 802_484; string fName = "Michael"; string lName = "Tindal"; double salary = 16.06 return new Employee() { EmployeeNumber = number, FirstName = fName, LastName = lName, HourlySalary = salary }; } } @functions{ public record Employee { public int EmployeeNumber { get; set; } public string? FirstName { get; set; } public string? LastName { get; set; } public double HourlySalary { get; set; } } }
An Argumented Record
Since a record is a type, you can pass it as argument. To do that, when creating the function, specify the type of a parameter as a record type. In the body of the function, use or ignore the parameter. When calling the function, make sure you pass an argument that holds a record type. Here is an example:
@page @model Exercises.Pages.ExerciseModel @using static System.Console @{ Employee Create() { return new Employee() { EmployeeNumber = 802_484, FirstName = "Michael", LastName = "Tindal", HourlySalary = 16.06 }; } void Show(Employee staff) { WriteLine("========================================="); WriteLine(" - Human Resources -"); WriteLine("-----------------------------------------"); WriteLine("-=- Employee Detials -=-"); WriteLine("========================================="); WriteLine($"Employee #: {staff.EmployeeNumber}"); WriteLine($"First Name: {staff.FirstName}"); WriteLine($"Last Name: {staff.LastName}"); WriteLine($"Gross Salary: {staff.FirstName}"); WriteLine($"Last Name: {staff.HourlySalary:f}"); WriteLine("========================================="); } Employee staff = Create(); Show(staff); } @functions{ public record Employee { public int EmployeeNumber { get; set; } public string? FirstName { get; set; } public string? LastName { get; set; } public double HourlySalary { get; set; } } }
Here is an example of running the program:
============================================ - Human Resources - -------------------------------------------- -=- Employee Detials -=- ============================================ Employee #: 913740 First Name: Jennifer Last Name: Beals Gross Salary: Jennifer Last Name: 31.25 ============================================
Records and Records
A Record as a Type
A record can be involved with other records as normally as a type can be. For example, a property of a record can be a record type. If you need to display a caption on it, at design time, in the Properties window, click Text and type a string. To do this programmatically, assign a string to the Text property of the group box control. Here is an example:
public record Identification { public string Abbreviation { get; set; } public string GeneralName { get; set; } public string ISOName { get; set; } } public record State { public Identification Identification { get; set; } public string Capital { get; set; } public long Area { get; set; } public long Population { get; set; } }
We have already seen that a property can be a record type. In the same way, a property of a record can be a type of another record.
Records and Inheritance
Records support inheritance, but a record can be derived only from another record. This means that you must first have a record that would serve as parent. Here is an example:
public record Employee { public int EmployeeNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public double HourlySalary { get; set; } } public record Manager : Employee { public string JobTitle { get; set; } public bool CanUnlockAccount { get; set; } }
Inheriting from Object
If you have a good functioning class that lays a foundation that can benefit other objects, unfortunately, you cannot derive a record from it. As a result, the following code will produce an error:
public class Vehicle { public int Doors { get; set; } } public record Tractor : Vehicle { public string ModelName { get; set; } public float EnginePower { get; set; } public int LiftCapacity { get; set; } public int MowerHeight { get; set; } public decimal Price { get; set; } }
This error is because you cannot create a record that is based on a class. There is an exception. Remember that every time you create a class in your C# application, the class is automatically derived from the object type. That concept also applies to structures and records. In fact, when you create a record, you can indicate that it derives from object. Here is an example:
@page
@model Exercises.Pages.ExerciseModel
@using static System.Console
@{
Tractor machine = new Tractor();
machine.ModelName = "MW9724";
machine.EnginePower = 21.5f;
machine.LiftCapacity = 754;
machine.MowerHeight = 60;
machine.Price = 13_050;
WriteLine("Tractor Characteristics");
WriteLine("=============================");
WriteLine($"Model Name: {machine.ModelName}");
WriteLine($"Engine Power: {machine.EnginePower} hp");
WriteLine($"Lift Capacity: {machine.ModelName} lbs");
WriteLine($"Mower Height: {machine.MowerHeight}");
WriteLine($"Price: {machine.Price:C}");
WriteLine("=============================");
}
@functions{
public record Tractor : object
{
public string? ModelName { get; set; }
public float EnginePower { get; set; }
public int LiftCapacity { get; set; }
public int MowerHeight { get; set; }
public decimal Price { get; set; }
}
}
This would produce:
Tractor Characteristics ============================= Model Name: MW9724 Engine Power: 21.5 hp Lift Capacity: MW9724 lbs Mower Height: 60 Price: $13,050.00 =============================
Probably the primary characteristic of the object class is that ot provides the primary features, mainly methods that all C# classes would need. One of these methods is the abiliby to find out whether two objects are equal. To make this happen, when you create a class, you can/must override the Equals() method. When it comes to records, the ability to compare two records objects is built in the record concept. Therefore, if you create a record, you cannot (you are not allowed to) override the Equals() method. If you do, you would receive an error.
Records and Classes
A Member of a Class Type
A member of a record, as a field or property, can be of the type of a class. You can use a .NET built-in class or you can create your own class. Then, on the body of a record, create a member whose type is a class. Here is an example:
public enum ChargeStatus { Negative, Neutral, Positive, Unknown } // A class type public class Nucleus { // A nucleus is made of one or more protons and neutrons public int Protons { get; set; } public int Neutrons { get; set; } } // A record layout public record Atom { // An atom is made of a nucleus (and one or more electrons public Nucleus Nucleus { get; set; } public int Electrons { get; set; } public ChargeStatus ChargeStatus { get; set; } }
A Record for a Class Member
The type of a member of a class, such as a field or a property, can be based on a record. When creating the member, simply specify its type as an existing record. You can then use the member as regularly as necessary. Here is an example:
public record Employee { public int EmployeeNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } internal record IncomeTax { public int TaxIdentifier { get; set; } public Employee Employee { get; set; } = new Employee(); public double GrossSalary { get; set; } }
Records and Constructors
Introduction
Both the classes and the structures support constructors, quite in the same way (before C# 10.0, classes and structures dealt with constructors differently; for example, prior to C# 10.0, you were not allowed to create a default constructor (a constructor without a parameter) in a structure, starting with C# 10.0, you can). Constructors are a little different and particularly important in records.
So far, we didn't create constructors for our records but, like classes and constructors, a record can have constructors. In fact, if you create a record without a constructor, the compiler would create a default constructor for you. Still, if you want, you can create a default constructor in your record. Here is an example:
public record VehicleRegistration
{
public VehicleRegistration()
{
}
}
Of course, when you use the default constructor to instantiate a record object, you can use the curly brackets to make a list of the properties of the record and provide a value for each. Here is an example:
@page
@model Exercises.Pages.ExerciseModel
@using static System.Console
@{
VehicleRegistration vr = new VehicleRegistration()
{
TagNumber = "HPR-385",
Make = "Ford",
Model = "Escape",
Year = 2020
};
}
@functions{
public record VehicleRegistration
{
int yr;
string _nbr;
string _make, _model;
public VehicleRegistration()
{
}
public string TagNumber
{
get
{
return _nbr;
}
set
{
_nbr = value;
}
}
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int Year
{
get { return yr; }
set { yr = value; }
}
}
}
<pre>Vehicle Registration
====================="
Tag #: @vr.TagNumber
Make: @vr.Make
Model: @vr.Model
Year: @vr.Year
=====================</pre>
This would produce:
Vehicle Registration ===================== Tag #: HPR-385 Make: Ford Model: Escape Year: 2020 =====================
A Parameterized Constructor
If you judge it necessary, when creating a record, you can create a constructor that takes at least one parameter. Here is an example:
public record VehicleRegistration
{
string _nbr;
public VehicleRegistration(string number)
{
}
}
You can then use such a constructor to create an object of the record. Here is an example:
@page
@model Exercises.Pages.ExerciseModel
@using static System.Console
@{
VehicleRegistration vr = new VehicleRegistration("HPR-385");
vr.Make = "Ford";
vr.Model = "Escape";
vr.Year = 2020;
}
@functions{
public record VehicleRegistration
{
int yr;
string _nbr;
string _make, _model;
public VehicleRegistration(string number)
{
_nbr = number;
}
. . .
}
}
<pre>Vehicle Registration
=====================");
Tag #: @vr.TagNumber
Make: @vr.Make
Model: @vr.Model
Year: @vr.Year
=====================</pre>
As mentioned with classes (and valid for structures), if you create a constructor in a record and that constructor takes at least one parameter, the default constructor disappears. The solution is to manually create various constructors because, as we saw with methods, records support method overloading. To do this, create constructors that takes different numbers or different types of parameters. You can then call each constructor as needed. Here are examples:
@{ // Using the default constructor to create an object VehicleRegistration vr = new VehicleRegistration() { TagNumber = "HPR-385", Make = "Ford", Model = "Escape", Year = 2020 }; // Using a constructor with one parameter VehicleRegistration vehicle = new VehicleRegistration("937052") { Make = "Toyota", Model = "Corolla", Year = 1998 }; // A constructor with two parameters VehicleRegistration register = new VehicleRegistration("Buick", "LeSabre") { TagNumber = "FKE-RLW", Year = 2020 }; // A public constructor VehicleRegistration registration = new VehicleRegistration("GH4-G88", "Lincoln", "Continental", 2006); } @functions{ public record VehicleRegistration { int yr; string _nbr; string _make, _model; public VehicleRegistration() { _nbr = "000-000"; _make = "Collectible"; _model = "Classic"; yr = 1960; } public VehicleRegistration(string number) { _nbr = number; } public VehicleRegistration(string make, string model) { _make = make; _model = model; } public VehicleRegistration(string nbr, string make, string model, int year) { _nbr = nbr; _make = make; _model = model; yr = year; } public string TagNumber { get { return _nbr; } set { _nbr = value; } } public string Make { get { return _make; } set { _make = value; } } public string Model { get { return _model; } set { _model = value; } } public int Year { get { return yr; } set { yr = value; } } } }
Initializing a Property
We know that you can create a property with a set clause, in which case you can let the clients the record assign a desired value to the property after an object of the record has been created. Here are examples of such properties:
@page @model Valuable.Pages.CreatureModel @using static System.Console @{ Canoe fun = new Canoe(); fun.Identification = 280_385; fun.Make = "Emotion"; fun.Model = "Wasatch "; fun.Length = 13; fun.Price = 479.99; } @functions{ public record Canoe { int id; int len; double cost; string? _make; string? _model; public int Identification { get { return id; } set { id = value; } } public string? Make { get { return _make; } set { _make = value; } } public string? Model { get { return _model; } set { _model = value; } } public int Length { get { return len; } set { len = value; } } public double Price { get { return cost; } set { cost = value; } } } } <pre>Canoe Registration ===================== Identifier: @fun.Identification --------------------- Make: @fun.Make Model: @fun.Model Length: @fun.Length Price: @fun.Price =====================</pre>
This would produce:
Canoe Registration ===================== Identifier: 280385 --------------------- Make: Emotion Model: Wasatch Length: 13 Price: 479.99 =====================
If you want to require that a certain property be given a value immediately when a record object is created, you must create an init clause insteat of a set clause. Here is an example:
public record Canoe
{
int id;
public int Identification
{
get { return id; }
init { id = value; }
}
}
After doing that, the property must receive a value immediately when the record is instantiated. To make this happen, you have two options. When you create an object of the record, you can use the curly brackets to initialize the object. This can be done as follows:
@page @model Valuable.Pages.CreatureModel @using static System.Console @{ Canoe fun = new Canoe() { Make = "Emotion", Model = "Wasatch ", Identification = 280_385, Length = 13, Price = 479.99 }; } @functions{ public record Canoe { int id; int len; double cost; string? _make; string? _model; public int Identification { get { return id; } init { id = value; } } public string? Make { get { return _make; } set { _make = value; } } public string? Model { get { return _model; } set { _model = value; } } public int Length { get { return len; } set { len = value; } } public double Price { get { return cost; } set { cost = value; } } } } <pre>Canoe Registration ===================== Identifier: @fun.Identification --------------------- Make: @fun.Make Model: @fun.Model Length: @fun.Length Price: @fun.Price =====================</pre>
An alternate solution is to create a constructor in the record. That constructor must have a parameter for he property. In the body of the constructor, assign the parameter to property or to its associated field. This can be done as follows:
@page @model Valuable.Pages.CreatureModel @using static System.Console @{ Canoe fun = new Canoe(280_385); fun.Make = "Emotion"; fun.Model = "Wasatch "; fun.Length = 13; fun.Price = 479.99; } @functions{ public record Canoe { int id; int len; double cost; string? _make; string? _model; public Canoe(int number) { id = number; } public int Identification { get { return id; } init { id = value; } } public string? Make { get { return _make; } set { _make = value; } } public string? Model { get { return _model; } set { _model = value; } } public int Length { get { return len; } set { len = value; } } public double Price { get { return cost; } set { cost = value; } } } } <pre>Canoe Registration ===================== Identifier: @fun.Identification --------------------- Make: @fun.Make Model: @fun.Model Length: @fun.Length Price: @fun.Price =====================</pre>
In the same way, in a record, you can create various properties that have init clauses. You can have a mix of properties with set and init clauses. You can also create automatic properties that usse init clauses. Remember that, when you are creating an object of the record, you must use one of both options we reviewed to initialize an caption property. Here is an example:
@page
@model Valuable.Pages.CreatureModel
@using static System.Console
@{
Canoe fun = new(280_385)
{
Make = "Emotion",
Model = "Wasatch "
};
fun.Length = 13;
fun.Price = 479.99;
}
@functions{
public record Canoe
{
public Canoe(int number)
{
Identification = number;
}
public int Identification { get; init; }
public string? Make { get; init; }
public string? Model { get; init; }
public int Length { get; set; }
public double Price { get; set; }
}
}
<pre>Canoe Registration
=====================
Identifier: @fun.Identification
---------------------
Make: @fun.Make
Model: @fun.Model
Length: @fun.Length
Price: @fun.Price
=====================</pre>
Practical Learning: Using Records
namespace PayrollPreparation3.Models { public record Employee { public int EmployeeNumber { get; init; } public string? FirstName { get; init; } public string? LastName { get; init; } public double HourlySalary { get; init; } } }
namespace PayrollPreparation3.Models { internal record DayWork { private double tm; private readonly Employee worker; public DayWork(Employee staff, double time) { tm = time; worker = staff; } public double TimeWorked { get { return tm; } init { tm = value; } } public double RegularTime { get { if (tm is <= 8.00) return tm; else return 8.00; } } public double Overtime { get { if (tm is <= 8.00) return 0.00; else return tm - 8.00; } } public double RegularPay { get { return worker.HourlySalary * RegularTime; } } public double OvertimePay { get { return worker.HourlySalary * 1.50 * Overtime; } } public double NetPay { get { return RegularPay + OvertimePay; } } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - Payroll Preparation</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /> <link rel="stylesheet" href="~/css/PayrollPreparation.css" asp-append-version="true" /> </head> <body> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3 top-bar"> <div class="container"> <a class="navbar-brand" asp-area="" asp-page="/Index">Payroll Preparation</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between"> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-white" asp-area="" asp-page="/Index">Home</a> </li> <li class="nav-item"> <a class="nav-link text-white" asp-area="" asp-page="/Privacy">Privacy</a> </li> </ul> </div> </div> </nav> </header> <div class="container"> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> <p class="text-center common-font">© 2022 - Payroll Preparation - <a asp-area="" asp-page="/Privacy">Privacy</a></p> </div> </footer> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html>
@page @model IndexModel @using PayrollPreparation3.Models @using static System.Console @{ string? strWeek1Monday = null, strWeek1Tuesday = null, strWeek1Wednesday = null, strWeek1Thursday = null, strWeek1Friday = null; string? strWeek2Monday = null, strWeek2Tuesday = null, strWeek2Wednesday = null, strWeek2Thursday = null, strWeek2Friday = null; string? strWeek1MondayRegularTime = null, strWeek1TuesdayRegularTime = null, strWeek1WednesdayRegularTime = null, strWeek1ThursdayRegularTime = null, strWeek1FridayRegularTime = null; string? strWeek2MondayRegularTime = null, strWeek2TuesdayRegularTime = null, strWeek2WednesdayRegularTime = null, strWeek2ThursdayRegularTime = null, strWeek2FridayRegularTime = null; string? strWeek1MondayOvertime = null, strWeek1TuesdayOvertime = null, strWeek1WednesdayOvertime = null, strWeek1ThursdayOvertime = null, strWeek1FridayOvertime = null; string? strWeek2MondayOvertime = null, strWeek2TuesdayOvertime = null, strWeek2WednesdayOvertime = null, strWeek2ThursdayOvertime = null, strWeek2FridayOvertime = null; string? strWeek1MondayRegularPay = null, strWeek1TuesdayRegularPay = null, strWeek1WednesdayRegularPay = null, strWeek1ThursdayRegularPay = null, strWeek1FridayRegularPay = null; string? strWeek2MondayRegularPay = null, strWeek2TuesdayRegularPay = null, strWeek2WednesdayRegularPay = null, strWeek2ThursdayRegularPay = null, strWeek2FridayRegularPay = null; string? strWeek1MondayOvertimePay = null, strWeek1TuesdayOvertimePay = null, strWeek1WednesdayOvertimePay = null, strWeek1ThursdayOvertimePay = null, strWeek1FridayOvertimePay = null; string? strWeek2MondayOvertimePay = null, strWeek2TuesdayOvertimePay = null, strWeek2WednesdayOvertimePay = null, strWeek2ThursdayOvertimePay = null, strWeek2FridayOvertimePay = null; string? strWeek1MondayNetPay = null, strWeek1TuesdayNetPay = null, strWeek1WednesdayNetPay = null, strWeek1ThursdayNetPay = null, strWeek1FridayNetPay = null; string? strWeek2MondayNetPay = null, strWeek2TuesdayNetPay = null, strWeek2WednesdayNetPay = null, strWeek2ThursdayNetPay = null, strWeek2FridayNetPay = null; string? strWeek1Salary = null, strWeek2Salary = null, strNetPay = null; Employee employee = new(); DayWork? dwWk1Monday = null, dwWk1Tuesday = null, dwWk1Wednesday = null, dwWk1Thursday = null, dwWk1Friday = null; DayWork? dwWk2Monday = null, dwWk2Tuesday = null, dwWk2Wednesday = null, dwWk2Thursday = null, dwWk2Friday = null; if (Request.HasFormContentType) { double wk1Monday = 0.00, wk1Tuesday = 0.00, wk1Wednesday = 0.00, wk1Thursday = 0.00, wk1Friday = 0.00; double wk2Monday = 0.00, wk2Tuesday = 0.00, wk2Wednesday = 0.00, wk2Thursday = 0.00, wk2Friday = 0.00; int emplNbr = 0; double hSalary = 0.00; try { emplNbr = int.Parse(Request.Form["txtEmployeeNumber"]); } catch (FormatException) { WriteLine("You must provide a valid unique number for the employee."); } string? firstName = Request.Form["txtFirstName"]; string? lastName = Request.Form["txtLastName"]; try { hSalary = double.Parse(Request.Form["txtHourlySalary"]); } catch (FormatException) { WriteLine("You must provide a valid unique number for the employee."); } employee = new() { EmployeeNumber = emplNbr, FirstName = firstName, LastName = lastName, HourlySalary = hSalary }; try { wk1Monday = double.Parse(Request.Form["txtWeek1Monday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Monday for the first week."); } try { wk1Tuesday = double.Parse(Request.Form["txtWeek1Tuesday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Tuesday for the first week."); } try { wk1Wednesday = double.Parse(Request.Form["txtWeek1Wednesday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Wednesday for the first week."); } try { wk1Thursday = double.Parse(Request.Form["txtWeek1Thursday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Thursday for the first week."); } try { wk1Friday = double.Parse(Request.Form["txtWeek1Friday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Friday for the first week."); } try { wk2Monday = double.Parse(Request.Form["txtWeek2Monday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Monday for the second week."); } try { wk2Tuesday = double.Parse(Request.Form["txtWeek2Tuesday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Tuesday for the second week."); } try { wk2Wednesday = double.Parse(Request.Form["txtWeek2Wednesday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Wednesday for the second week."); } try { wk2Thursday = double.Parse(Request.Form["txtWeek2Thursday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Thursday for the second week."); } try { wk2Friday = double.Parse(Request.Form["txtWeek2Friday"]); } catch (FormatException) { WriteLine("You must provide a valid value for the time worked on Friday for the second week."); } dwWk1Monday = new(employee, wk1Monday); dwWk1Tuesday = new(employee, wk1Tuesday); dwWk1Wednesday = new(employee, wk1Wednesday); dwWk1Thursday = new(employee, wk1Thursday); dwWk1Friday = new(employee, wk1Friday); dwWk2Monday = new(employee, wk2Monday); dwWk2Tuesday = new(employee, wk2Tuesday); dwWk2Wednesday = new(employee, wk2Wednesday); dwWk2Thursday = new(employee, wk2Thursday); dwWk2Friday = new(employee, wk2Friday); strWeek1Monday = $"{wk1Monday:F}"; strWeek1Tuesday = $"{wk1Tuesday:F}"; strWeek1Wednesday = $"{wk1Wednesday:F}"; strWeek1Thursday = $"{wk1Thursday:F}"; strWeek1Friday = $"{wk1Friday:F}"; strWeek1MondayRegularTime = $"{dwWk1Monday.RegularTime:F}"; strWeek1TuesdayRegularTime = $"{dwWk1Tuesday.RegularTime:F}"; strWeek1WednesdayRegularTime = $"{dwWk1Wednesday.RegularTime:F}"; strWeek1ThursdayRegularTime = $"{dwWk1Thursday.RegularTime:F}"; strWeek1FridayRegularTime = $"{dwWk1Friday.RegularTime:F}"; strWeek1MondayOvertime = $"{dwWk1Monday.Overtime:F}"; strWeek1TuesdayOvertime = $"{dwWk1Tuesday.Overtime:F}"; strWeek1WednesdayOvertime = $"{dwWk1Wednesday.Overtime:F}"; strWeek1ThursdayOvertime = $"{dwWk1Thursday.Overtime:F}"; strWeek1FridayOvertime = $"{dwWk1Friday.Overtime:F}"; strWeek1MondayRegularPay = $"{dwWk1Monday.RegularPay:F}"; strWeek1TuesdayRegularPay = $"{dwWk1Tuesday.RegularPay:F}"; strWeek1WednesdayRegularPay = $"{dwWk1Wednesday.RegularPay:F}"; strWeek1ThursdayRegularPay = $"{dwWk1Thursday.RegularPay:F}"; strWeek1FridayRegularPay = $"{dwWk1Friday.RegularPay:F}"; strWeek1MondayOvertimePay = $"{dwWk1Monday.OvertimePay:F}"; strWeek1TuesdayOvertimePay = $"{dwWk1Tuesday.OvertimePay:F}"; strWeek1WednesdayOvertimePay = $"{dwWk1Wednesday.OvertimePay:F}"; strWeek1ThursdayOvertimePay = $"{dwWk1Thursday.OvertimePay:F}"; strWeek1FridayOvertimePay = $"{dwWk1Friday.OvertimePay:F}"; strWeek1MondayNetPay = $"{dwWk1Monday.NetPay:F}"; strWeek1TuesdayNetPay = $"{dwWk1Tuesday.NetPay:F}"; strWeek1WednesdayNetPay = $"{dwWk1Wednesday.NetPay:F}"; strWeek1ThursdayNetPay = $"{dwWk1Thursday.NetPay:F}"; strWeek1FridayNetPay = $"{dwWk1Friday.NetPay:F}"; strWeek2Monday = $"{wk2Monday:F}"; strWeek2Tuesday = $"{wk2Tuesday:F}"; strWeek2Wednesday = $"{wk2Wednesday:F}"; strWeek2Thursday = $"{wk2Thursday:F}"; strWeek2Friday = $"{wk2Friday:F}"; strWeek2MondayRegularTime = $"{dwWk2Monday.RegularTime:F}"; strWeek2TuesdayRegularTime = $"{dwWk2Tuesday.RegularTime:F}"; strWeek2WednesdayRegularTime = $"{dwWk2Wednesday.RegularTime:F}"; strWeek2ThursdayRegularTime = $"{dwWk2Thursday.RegularTime:F}"; strWeek2FridayRegularTime = $"{dwWk2Friday.RegularTime:F}"; strWeek2MondayOvertime = $"{dwWk2Monday.Overtime:F}"; strWeek2TuesdayOvertime = $"{dwWk2Tuesday.Overtime:F}"; strWeek2WednesdayOvertime = $"{dwWk2Wednesday.Overtime:F}"; strWeek2ThursdayOvertime = $"{dwWk2Thursday.Overtime:F}"; strWeek2FridayOvertime = $"{dwWk2Friday.Overtime:F}"; strWeek2MondayRegularPay = $"{dwWk2Monday.RegularPay:F}"; strWeek2TuesdayRegularPay = $"{dwWk2Tuesday.RegularPay:F}"; strWeek2WednesdayRegularPay = $"{dwWk2Wednesday.RegularPay:F}"; strWeek2ThursdayRegularPay = $"{dwWk2Thursday.RegularPay:F}"; strWeek2FridayRegularPay = $"{dwWk2Friday.RegularPay:F}"; strWeek2MondayOvertimePay = $"{dwWk2Monday.OvertimePay:F}"; strWeek2TuesdayOvertimePay = $"{dwWk2Tuesday.OvertimePay:F}"; strWeek2WednesdayOvertimePay = $"{dwWk2Wednesday.OvertimePay:F}"; strWeek2ThursdayOvertimePay = $"{dwWk2Thursday.OvertimePay:F}"; strWeek2FridayOvertimePay = $"{dwWk2Friday.OvertimePay:F}"; strWeek2MondayNetPay = $"{dwWk2Monday.NetPay:F}"; strWeek2TuesdayNetPay = $"{dwWk2Tuesday.NetPay:F}"; strWeek2WednesdayNetPay = $"{dwWk2Wednesday.NetPay:F}"; strWeek2ThursdayNetPay = $"{dwWk2Thursday.NetPay:F}"; strWeek2FridayNetPay = $"{dwWk2Friday.NetPay:F}"; strWeek1Salary = $"{(dwWk1Monday.NetPay + dwWk1Tuesday.NetPay + dwWk1Wednesday.NetPay + dwWk1Thursday.NetPay + dwWk1Friday.NetPay):F}"; strWeek2Salary = $"{(dwWk2Monday.NetPay + dwWk2Tuesday.NetPay + dwWk2Wednesday.NetPay + dwWk2Thursday.NetPay + dwWk2Friday.NetPay):F}"; double netPay = dwWk1Monday.NetPay + dwWk1Tuesday.NetPay + dwWk1Wednesday.NetPay + dwWk1Thursday.NetPay + dwWk1Friday.NetPay + dwWk2Monday.NetPay + dwWk2Tuesday.NetPay + dwWk2Wednesday.NetPay + dwWk2Thursday.NetPay + dwWk2Friday.NetPay; strNetPay = $"{netPay:F}"; } } <h1 class="common-font text-center bold">Payroll Preparation</h1> <hr /> <form name="PayrollEvaluation" method="post" class="common-font"> <h3 class="text-center bold">Employee Information</h3> <hr /> <table style="width: 625px" align="center"> <tr> <td style="width: 125px">@Html.Label("txtFirstName", "First Name:", new { @class = "bold" })</td> <td>@Html.TextBox("txtFirstName", @employee.FirstName, new { @class = "form-control" })</td> <td>@Html.Label("txtLastName", "Last Name:", new { @class = "bold" })</td> <td>@Html.TextBox("txtLastName", @employee.LastName, new { @class = "form-control" })</td> </tr> <tr> <td>@Html.Label("txtEmployeeNumber", "Employee #:", new { @class = "bold" })</td> <td>@Html.TextBox("txtEmployeeNumber", @employee.EmployeeNumber, new { @class = "form-control align-right" })</td> <td class="bold">Hourly Salary:</td> <td>@Html.TextBox("txtHourlySalary", @employee.HourlySalary, new { @class = "form-control align-right" })</td> </tr> </table> <hr /> <h3 class="text-center bold">Time Sheet - Time Worked</h3> <hr /> <table style="width: 625px" align="center"> <tr style="border-bottom: 1px solid black"> <td> </td> <td class="text-center bold">Monday</td> <td class="text-center bold">Tuesday</td> <td class="text-center bold">Wednesday</td> <td class="text-center bold">Thursday</td> <td class="text-center bold">Friday</td> </tr> <tr> <td style="width: 125px" class="bold">Week 1:</td> <td>@Html.TextBox("txtWeek1Monday", @strWeek1Monday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek1Tuesday", @strWeek1Tuesday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek1Wednesday", @strWeek1Wednesday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek1Thursday", @strWeek1Thursday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek1Friday", @strWeek1Friday, new { @class="form-control align-right" })</td> </tr> <tr> <td class="bold">Week 2:</td> <td>@Html.TextBox("txtWeek2Monday", @strWeek2Monday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek2Tuesday", @strWeek2Tuesday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek2Wednesday", @strWeek2Wednesday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek2Thursday", @strWeek2Thursday, new { @class="form-control align-right" })</td> <td>@Html.TextBox("txtWeek2Friday", @strWeek2Friday, new { @class="form-control align-right" })</td> </tr> </table> <hr /> <table style="width: 300px" align="center"> <tr> <td style="width: 50px"> </td> <td><input type="submit" value="Evaluate Payroll" name="btnEvaluatePayroll" style="width: 150px" /></td> </tr> </table> <hr /> <h3 class="text-center bold">Time and Pay Summary</h3> <hr /> <table style="width: 625px" align="center"> <tr style="border-bottom: 1px solid black"> <td class="bold">Week 1</td> <td class="text-center bold">Monday</td> <td class="text-center bold">Tuesday</td> <td class="text-center bold">Wednesday</td> <td class="text-center bold">Thursday</td> <td class="text-center bold">Friday</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Regular Time:</td> <td class="text-center">@strWeek1MondayRegularTime</td> <td class="text-center">@strWeek1TuesdayRegularTime</td> <td class="text-center">@strWeek1WednesdayRegularTime</td> <td class="text-center">@strWeek1ThursdayRegularTime</td> <td class="text-center">@strWeek1FridayRegularTime</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Overtime:</td> <td class="text-center">@strWeek1MondayOvertime</td> <td class="text-center">@strWeek1TuesdayOvertime</td> <td class="text-center">@strWeek1WednesdayOvertime</td> <td class="text-center">@strWeek1ThursdayOvertime</td> <td class="text-center">@strWeek1FridayOvertime</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Regular Pay:</td> <td class="text-center">@strWeek1MondayRegularPay</td> <td class="text-center">@strWeek1TuesdayRegularPay</td> <td class="text-center">@strWeek1WednesdayRegularPay</td> <td class="text-center">@strWeek1ThursdayRegularPay</td> <td class="text-center">@strWeek1FridayRegularPay</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Overtime Pay:</td> <td class="text-center">@strWeek1MondayOvertimePay</td> <td class="text-center">@strWeek1TuesdayOvertimePay</td> <td class="text-center">@strWeek1WednesdayOvertimePay</td> <td class="text-center">@strWeek1ThursdayOvertimePay</td> <td class="text-center">@strWeek1FridayOvertimePay</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Net Pay:</td> <td class="text-center">@strWeek1MondayNetPay</td> <td class="text-center">@strWeek1TuesdayNetPay</td> <td class="text-center">@strWeek1WednesdayNetPay</td> <td class="text-center">@strWeek1ThursdayNetPay</td> <td class="text-center">@strWeek1FridayNetPay</td> </tr> <tr style="border-bottom: 1px solid black"> <td> </td> <td> </td> <td> </td> <td> </td> <td class="bold">Week 1 Salary:</td> <td class="text-center">@strWeek1Salary</td> </tr> </table> <hr /> <table style="width: 625px" align="center"> <tr style="border-bottom: 1px solid black"> <td class="bold">Week 2</td> <td class="text-center bold">Monday</td> <td class="text-center bold">Tuesday</td> <td class="text-center bold">Wednesday</td> <td class="text-center bold">Thursday</td> <td class="text-center bold">Friday</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Regular Time:</td> <td class="text-center">@strWeek2MondayRegularTime</td> <td class="text-center">@strWeek2TuesdayRegularTime</td> <td class="text-center">@strWeek2WednesdayRegularTime</td> <td class="text-center">@strWeek2ThursdayRegularTime</td> <td class="text-center">@strWeek2FridayRegularTime</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Overtime:</td> <td class="text-center">@strWeek2MondayOvertime</td> <td class="text-center">@strWeek2TuesdayOvertime</td> <td class="text-center">@strWeek2WednesdayOvertime</td> <td class="text-center">@strWeek2ThursdayOvertime</td> <td class="text-center">@strWeek2FridayOvertime</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Regular Pay:</td> <td class="text-center">@strWeek2MondayRegularPay</td> <td class="text-center">@strWeek2TuesdayRegularPay</td> <td class="text-center">@strWeek2WednesdayRegularPay</td> <td class="text-center">@strWeek2ThursdayRegularPay</td> <td class="text-center">@strWeek2FridayRegularPay</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Overtime Pay:</td> <td class="text-center">@strWeek2MondayOvertimePay</td> <td class="text-center">@strWeek2TuesdayOvertimePay</td> <td class="text-center">@strWeek2WednesdayOvertimePay</td> <td class="text-center">@strWeek2ThursdayOvertimePay</td> <td class="text-center">@strWeek2FridayOvertimePay</td> </tr> <tr style="border-bottom: 1px solid black"> <td class="bold">Net Pay:</td> <td class="text-center">@strWeek2MondayNetPay</td> <td class="text-center">@strWeek2TuesdayNetPay</td> <td class="text-center">@strWeek2WednesdayNetPay</td> <td class="text-center">@strWeek2ThursdayNetPay</td> <td class="text-center">@strWeek2FridayNetPay</td> </tr> <tr style="border-bottom: 1px solid black"> <td> </td> <td> </td> <td> </td> <td> </td> <td class="bold">Week 2 Salary:</td> <td class="text-center">@strWeek2Salary</td> </tr> <tr style="border-bottom: 1px solid black"> <td> </td> <td> </td> <td> </td> <td> </td> <td class="bold">Net Pay:</td> <td class="text-center">@strNetPay</td> </tr> </table> </form>
Employee Number: 297480 First Name: Roger Last Name: Thristen Hourly Salary: 28.47 Time Worked - Week 1 Monday: 6.5 Tuesday: 8 Wednesday: 6 Thursday: 8 Friday: 7.5 Time Worked - Week 2 Monday: 9 Tuesday: 8.5 Wednesday: 10.5 Thursday: 8 Friday: 9.5
A Record With Positional Parameters
Introduction
We have learned that a record can contain one or more constructors. As a simple way to create a record, you can use the formula of a constructor. The formula to follow is:
options record name(parameter-name(s));
As always, start with one or more appropriate options. The most basic option is an access level, such as public. Use the record keyword to indicate that you are creating a record type. Add a name for the record. The name follows the rules of names of classes.
Our formula is as if you are creating a constructor of a record without creating a body delimited by curly brackets. Since a constructor is a method, you must apply parentheses to the name of the record. In the parentheses, create a parameter for each property you would have added if you had created the record in a classic way. End the statement with a semicolon. This technique is referred to as a record with positional parameters. Here is an example:
public record Battery(string PartNumber, string Identification, double Price);
This is the descritîon of a record (as a kind of class or structure) with three properties (two string properties and one double property).
The Properties of a Record With Positional Parameters
After creating a record as done above, you have a regular record equipped with properties and one constructor that takes a parameter for each property. Every property of such a record is an automatic property with a get and an init clauses. As a normal type, you can use this record to create an object and use it appropriately. For example, you can declare a variable of it and specify a value for each poisitional parameter. Remember that each parameter represents an init property. Therefore, while using a constructor, you must pass an argument for each parameter. Here is an example:
@page @model Valuable.Pages.CreatureModel @using static System.Console @{ Battery power = new Battery("928359", "ACDelco Gold 94RAGM", 164.95); } @functions{ public record Battery(string PartNumber, string Identification, double Price); } <pre>Vehicle Battery ==================================== Part #: @power.PartNumber ------------------------------------ Identification: @power.Identification Price: @power.Price ====================================</pre>
This would produce:
Vehicle Battery ======================================= Part #: 928359 --------------------------------------- Identification: ACDelco Gold 94RAGM Price: 164.95 =======================================
Default Positional Parameters
Remember that you must provide a parameter for each property of the record, but each property must be initialized when an object is created. We saw that there are two ways to initialize the object, and one way is with curly brackets. To use this way, you can provide a default value for each parameter. Here is an example:
public record Battery(string PartNumber = "", string Identification = "", double Price = 0.00);
This time, you can use curly brackets to initialize the object. Here is an example:
@page
@model Valuable.Pages.CreatureModel
@using static System.Console
@{
Battery power = new Battery()
{
PartNumber = "928359",
Identification = "ACDelco Gold 94RAGM",
Price = 164.95
};
}
@functions{
public record Battery(string PartNumber = "", string Identification = "", double Price = 0.00);
}
<pre>Vehicle Battery
====================================
Part #: @power.PartNumber
------------------------------------
Identification: @power.Identification
Price: @power.Price
====================================</pre>
A record is an immutable type. This means that, once you have created and initialized a record, you cannot change its value(s). What you can do is to make a copy of an existing record. To do this, create another record object and assign an existing record to it. You can then use the new record object like any variable. Here is an example:
@page @model Valuable.Pages.CreatureModel @using static System.Console @{ Battery power = new() { PartNumber = "928359", Identification = "ACDelco Gold 94RAGM", Price = 164.95 }; Battery current = power; } @functions{ public record Battery(string PartNumber = "", string Identification = "", double Price = 0.00); } <pre>Vehicle Battery ==================================== Part #: @current.PartNumber ------------------------------------ Identification: @current.Identification Price: @current.Price ====================================</pre>
You can then change the value of any property you want and apply that change to the copied record. To do this, you use a keyword named with. The formula to use it is:
record-declaration with { property-1 = value-1, property-2 = value-2, property-x = value-x};
Start with a record object, such as done when declaring a record variable. Add the with keyword followed by curly brackets. End the statement with a semi-colon. Between the curly brackets, type the name of a property of the record or a list of properties. Assign the desired but appropriate value to the property. If you want to specify the values of various properties, separate them with commas. When you perform this exercise, you would get a new record with values changed on the indicated properties. The properties you don't access would keep their values given in the original record object. Here is an example:
@page
@model Valuable.Pages.CreatureModel
@using static System.Console
@{
var power = new Battery()
{
PartNumber = "928359",
Identification = "ACDelco Gold 94RAGM",
Price = 164.95
};
Battery current = power with { PartNumber = "479605" };
}
@functions{
public record Battery(string PartNumber = "", string Identification = "", double Price = 0.00);
}
<pre>Vehicle Battery
====================================
Part #: @current.PartNumber
------------------------------------
Identification: @current.Identification
Price: @current.Price
====================================</pre>
This would produce:
Vehicle Battery ======================================= Part #: 479605 --------------------------------------- Identification: ACDelco Gold 94RAGM Price: 164.95 =======================================
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2001-2022, FunctionX | Wednesday 13 October 2021 | Next |
|