Introductory Topics on Properties
Introductory Topics on Properties
Introduction to Automatic Properties
A Read-Only Automatic Property
As you should be aware by now, a read-only property is one that only provides values to external objects that cannot write values to it. To help you easily create an automatic read-only property, the C# language provides a formula as follows:
access-level data-type property-name { get; }
Based on this, to create a read-only property, simply include get; in its curly brackets. Here is an example:
public class Book
{
public string ISBN { get; }
}
By the way, in previous versions of C#, to create a read-only property, you had to add private set; in the curly brackets. Here is an example:
public class Book
{
public string ISBN { get; private set; }
}
A Read-Write Automatic Property
If you want to create a simple read/write property that relays values between a class and the external objects, you don't have to create a local field for it. To help you easily create a property, the C# language provides a formula as follows:
access-level data-type property-name { get; set; }
To use this formula, declare what resembles a variable followed by { get; set; }. This is referred to as an automatic property. Here is an example of an automatic property:
class Rectangle
{
public double Width { get; set; }
}
Of course, a Boolean property can also be created as an automatic property. Here is an example:
public class Member
{
public bool Accepted { get; set; }
}
You can write get; and set; each on its own line. Here are examples:
@functions{ public class Ellipse { public double radius { get; set; } public double Radius { get; set; } public double Area { get { return Radius * radius * 3.14159265; } } } }
Initializing a Property
We already know that, when you have declared a variable, before displaying its value, you must initialize it. When it comes to properties, in our introductions, we saw that you can initialize a property from an object of its class. Here is an example:
@page
@model PracticalLearning.Pages.TimeSheetModel
@{
TimeSheet ts = new TimeSheet();
ts.PayRate = 18.73;
}
@functions{
public class TimeSheet
{
double rate;
public double PayRate
{
set
{
rate = value;
}
get
{
return rate;
}
}
public double TimeWorked { get; set; }
public double NetPay
{
get
{
return rate * TimeWorked;
}
}
}
}
<h3>Payroll Summary</h3>
<p>Pay Rate: @ts.PayRate</p>
In the same way, you can initialize an automatic property from a variable of its class. Here is an example:
@page
@model PracticalLearning.Pages.TimeSheetModel
@{
TimeSheet ts = new TimeSheet();
ts.PayRate = 18.73;
ts.TimeWorked = 40.00;
}
@functions{
public class TimeSheet
{
double rate;
public double PayRate
{
set
{
rate = value;
}
get
{
return rate;
}
}
public double TimeWorked { get; set; }
public double NetPay
{
get
{
return rate * TimeWorked;
}
}
}
}
<h3>Payroll Summary</h3>
<p>Pay Rate: @ts.PayRate</p>
When it comes to automatic properties, you can initialize an automatic property directly where it is created in the class. To do this, after the closing curly bracket of the property, type = and assign the desired value. Of course, you must end the statement with a semicolon. Here is an example:
@page
@model PracticalLearning.Pages.TimeSheetModel
@{
TimeSheet ts = new TimeSheet();
ts.PayRate = 18.73;
}
@functions{
public class TimeSheet
{
double rate;
public double PayRate
{
set
{
rate = value;
}
get
{
return rate;
}
}
public double TimeWorked { get; set; } = 40.00;
public double NetPay
{
get
{
return rate * TimeWorked;
}
}
}
}
<h3>Payroll Summary</h3>
<hr />
<pre>Hourly Salary: @ts.PayRate
Time Worked: @ts.TimeWorked
-------------------------------
Net Pay: @ts.NetPay</pre>
This would produce:
Payroll Summary Hourly Salary: 18.73 Time Worked: 40 ------------------------------- Net Pay: 749.2
A Property in a Page Model
We have already seen that a razor page starts from a class, and that class is primarily regular class like any other. Therefore, in the Page Model class of a razor page, you can create a property using any of the techniques we have applied so far. Here are examples:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Operations.Pages
{
public class AdditionModel : PageModel
{
public int Number1 { get; set; }
public int Number2 { get; set; }
public AdditionModel()
{
Number1 = 308_468;
Number2 = 904_805;
}
public void OnGet()
{
}
public int Calculate()
{
return Number1 + Number2;
}
}
}
If the property is an automatic one, you can initialize it in the Page Model class. Here is an example
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Valuable.Pages
{
public class ExerciseModel : PageModel
{
public string Equation { get; set; } = "3x + 6 = 18";
}
}
Once you have created a property in a Page Model class, to access the property in the corresponding Razor Page, use the @Model object. Here is an example:
@page @model Operations.Pages.AdditionModel @{ } <form method="post" name="frmExercise"> <table style="width: 300px"> <tr> <td style="width: 150px">Number 1:</td> <td><input type="text" id="txtOperand1" name="txtOperand1" value="@Model.Number1" style="width: 100px" /></td> </tr> <tr> <td>Number 2:</td> <td><input type="text" id="txtOperand2" name="txtOperand2" value="@Model.Number2" style="width: 100px" /></td> </tr> <tr> <td>@Model.Number1 + @Model.Number2 =</td> <td><input type="text" id="txtResult" name="txtResult" value="@Model.Calculate()" style="width: 100px" /></td> </tr> </table> </form>
A Property of a Class Type
Introduction
After creating a class, it becomes a data type in its own right. As a normal data type, it can be involved in any regular property issue. Of course, to involve a class in a property-related operation, you must first have a class. You can use one an existing class or you can create a new one. To start, we already know how to create a field of a class type. Here is an example:
class Camera { } class TrafficTicket { Camera cmr; }
A Regular Class Type
We already know that, to have a property reader, you can create a get clause that returns the field. Here is an example:
@functions{
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
private Camera cmr;
public Camera Recorder
{
get
{
return cmr;
}
}
}
}
In the body of the get clause, we already know that you can create some type of validation for the field (to accept or reject its value), but if you are creating a regular property that simply returns the field, you can make the property as an expression-body. Here is an example:
@functions{
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
private Camera cmr;
public Camera Recorder
{
get => cmr
}
}
}
On the other hand, if you want to get a property-writer, create a set clause. In its body, assign value to the field. Here is an example:
@functions{
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
private Camera cmr;
public Camera Recorder
{
set
{
cmr = value;
}
}
}
}
We will see that you can process the field value in the set clause. If you are planning to create a simple property that only assigns the property to the value contextual keyword, you can change the body of the set class into an expression-body. Here is an example:
@functions{
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
Camera cmr;
public Camera Recorder
{
set => cmr = value;
}
}
}
An Automatic Property of a Class Type
In some cases, you will want to process the members (fields, properties, etc) of the property that is of a class type. In some other cases, you will want a simple property that only represents a characteristic of an object based on the class. In this case, you can make the property automatic. You have various options.
If you want a simple property that only produces an object, you can create the property as an automatic one with only get. Here is an example:
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
public Camera Recorder
{
get;
}
}
If you want a property that only writes an object, create a write-only automatic property.
If you want a simple property that the clients of the class can both read from and write to, you can create the property as an automatic one. Here is an example:
@functions{
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
public Camera Recorder
{
get;
set;
}
}
}
Using a Property of a Class Type
Introduction
If you create a property of a value (primitive) type, you can immediately use it. Here is an example:
@page @model Valuable.Pages.FoundationsModel @{ Employee staff = new Employee(); staff.FullName = "Ebalé Mesô Mê Mvuu"; } @functions{ public class Employee { public string FullName { get; set; } } } @{ } <p>Employee Name: @staff.FullName
This would produce:
Employee Name: Ebalé Mesô Mê Mvuu
In this case, the (string) property was not initialized in the class where it was created, then that property was accessed and used where needed. If you use a property of a class type directly, you will receive an error. Here is an example:
@page @model Valuable.Pages.FoundationsModel @{ TrafficTicket tt = new TrafficTicket(); tt.Recorder.Location = "Freemont Drive and Winchester Road"; } @functions{ public class Camera { public string Location { get; set; } } public class TrafficTicket { public Camera Recorder { get; set; } } } <p>Infraction Location: @tt.Recorder.Location</p>
This would produce:
You must first initialize the property. You have many options.
Initializing a Property of a Class Type Before Use
Before using a property of a class, you can first initialize it from an object of the class. Here is an example:
@page @model Valuable.Pages.FoundationsModel @{ TrafficTicket tt = new TrafficTicket(); tt.Recorder = new Camera(); tt.Recorder.Location = "Freemont Drive and Winchester Road"; } @functions{ public class Camera { public string Location { get; set; } } public class TrafficTicket { public Camera Recorder { get; set; } } } <p>Infraction Location: @tt.Recorder.Location</p>
This would produce:
Infraction Location: Freemont Drive and Winchester Road
Initializing a Property of a Class Type When Creating it
Notice that, in the above code, you must remember to initialize the property of a class type before accessing the members of the property. For some reason, you may forget to initialize the property or you may do it wrongly. Probably the best way to get the property of the class type ready is to initialize the property when creating it. To do this, after the closing curly bracket of the property, use the new operator to initialize the property using a constructor of the class type. Here is an example:
@page
@model Valuable.Pages.FoundationsModel
@{
TrafficTicket tt = new TrafficTicket();
tt.Recorder.Location = "Freemont Drive and Winchester Road";
}
@functions{
public class Camera
{
public string Location { get; set; }
}
public class TrafficTicket
{
public Camera Recorder
{
get;
set;
} = new Camera();
}
}
<p>Infraction Location: @tt.Recorder.Location</p>
Properties and Inheritance
The Protected Members of a Class
Besides being made private, a member of a class can be protected to restrict its access. As seen for a private member, a protected member can be accessed by members of the same class. To let you protect a member of a class from non-deriving classes, the C# language provides a keyword named protected. Therefore, to indicate that a member is protected, set its access type to the protected keyword. Both or either properties and/or methods of a class can be protected. Here is an example of a protected field:
@functions{
internal class Circle
{
/* This protected field can be accessed by members of this class
* (constructors, methods, and properties) and members of a derived class. */
protected double radius;
/* These public members can be accessed by all types of objects. */
public Circle()
{
Radius = 0.00;
}
public Circle(double radius)
{
Radius = radius;
}
public double Radius
{
get
{
return radius;
}
set
{
radius = value;
}
}
public double Area
{
get
{
return Radius * Radius * 3.141592653589793238462643;
}
}
public double Diameter
{
get
{
return Radius * 2;
}
}
public double Circumferemce
{
get { return Diameter * 3.141592653589793238462643; }
}
}
}
The main difference between a private and a protected member is that a protected member can be accessed by the members of its class but also the members of (a) derived class(es). Here is an example:
@functions{
public class Cylinder : Circle
{
public double Height { get; set; }
public Cylinder(double baseRadius = 0.00, double height = 0.00)
{
radius = baseRadius;
Height = height;
}
public double LateralArea
{
get
{
return Circumferemce * Height;
}
}
public double Volume
{
get
{
return Area * Height;
}
}
}
}
If you try accessing a protected member in neiter its class nor in a derived class, you would produce an error.
If you create a member of a class and mark it as protected, the classes derived from its parent class, created in the current project or outside the current project, can access it. If you want the member to be accessed only by derived classes implemented in the same project but not the derived classes outside of the current project, mark the member as protected internal. Here are examples:
@functions{ public class Person { private string _name; private string _gdr; public Person(string name = "Not Available", string gender = "Unknown") { _name = name; _gdr = gender; } protected internal string FullName { get { return _name; } set { _name = value; } } protected internal string Gender { get { return _gdr; } set { _gdr = value; } } } }
By the way, you may remember that, to reduce your code, you can use the => operator:
@functions{ public class Circle { /* This protected field can be accessed by members of this class * (constructors, methods, and properties) and members of a derived class. */ protected double radius; public Circle() => Radius = 0.00; public Circle(double radius) => Radius = radius; public double Radius { get { return radius; } set { radius = value; } } public double Area => Radius * Radius * 3.141592653589793238462643; public double Diameter => Radius * 2; public double Circumferemce => Diameter * 3.141592653589793238462643; } public class Cylinder : Circle { public double Height { get; set; } public Cylinder(double baseRadius = 0.00, double height = 0.00) { radius = baseRadius; Height = height; } public double LateralArea => Circumferemce * Height; public double Volume => Area * Height; } }
Interfaces and Properties
A Property in an Interface
An interface can contain one or more properties. If the property is intended to be read-only, create it using the formula we saw for automatic read-only properties, that is, without a body. Here is an example:
interface IPolygon
{
double Area { get; }
}
When implementing the property, if it is a simple property that doesn't need to validate any value, you can simply apply the desired access level. Here is an example:
@functions{ interface IPolygon { double Area { get; } } public class Triangle : IPolygon { public double Area { get; } } }
Otherwise, you can create a body for the property.
In the same way, if the property is intended to be write-only, in the body of the interface, create it and then implement it in a deriving class.
If a property is intended to be read-write, create it without its body in the interface. When implementing the property in a class, if it is a simple property, create it as an automatic property. If the property must validate its value, you can first create a private field and use it in the clauses of the property.
A Property of an Interface Type
Imagine you create an interface as we did above. Here is an example:
@functions{ public interface IVehicle { int NumberOfTires { get; set; } int NumberOfDoors { get; set; } string Color { get; set; } } }
You can create one or more classes that implement such an interface. Here is an example:
@functions{ public class Sedan : IVehicle { public int NumberOfTires { get; set; } public int NumberOfDoors { get; set; } public int NumberOfSeats { get; set; } public string Color { get; set; } public string Make { get; set; } public string Model { get; set; } public int Year { get; set; } } }
A property of a class can be of the type of an interface. You primarily create the property like one that is based on a class. Here is an example:
using System;
public class RentalOrder
{
// Rental Order #
public int InvoiceNumber { get; set; }
// The employee/clerk who processes/processed the rental order
public string EmployeeeNumber { get; set; }
// The vehicle that was rented
public IVehicle Car { get; set; }
public string RentStartDate { get; set; }
public string RentEndDate { get; set; }
}
When it comes time to use an interface-type property, you may have to indicate where the values of the property come from. In fact, at one time, you may have to initialize the property. To do this, you should/can (must) use a class that implements the interface. Here are examples:
@{
void OrderProcessing()
{
RentalOrder ro = new RentalOrder();
ro.InvoiceNumber = 100001;
ro.EmployeeeNumber = "309-247";
ro.RentStartDate = "08/02/2018";
ro.RentEndDate = "08/17/2018";
ro.Car = new Sedan();
}
}
From the interface-based property, you can access only the members of the interface. As a result, the following code would produce an error because you are trying to access a member of the class but that member is not part of the interface:
@functions{
void OrderProcessing()
{
RentalOrder ro = new RentalOrder();
ro.InvoiceNumber = 100001;
ro.EmployeeeNumber = "309-247";
ro.RentStartDate = "08/02/2018";
ro.RentEndDate = "08/17/2018";
ro.Car = new Sedan();
ro.Car.Make = "Ford";
}
}
Therefore, as mentioned already, remember that you can access only the members of the interface. Here are examples:
@functions{
void OrderProcessing()
{
RentalOrder ro = new RentalOrder();
ro.InvoiceNumber = 100001;
ro.EmployeeeNumber = "309-247";
ro.RentStartDate = "08/02/2018";
ro.RentEndDate = "08/17/2018";
ro.Car.NumberOfTires = 4;
ro.Car.NumberOfDoors = 4;
ro.Car.NumberOfSeats = 5;
ro.Car.Color = Silver;
}
}
An interface cannot contain a constructor. Instead, you can create one or more constructors in a class that implements the interface. From a constructor, you can access any of the members of the interface.
Imagine you declare a variable using the name of an interface. Here is an example:
@functions{
void Calculate()
{
double measure = 319.77;
IPolygon et = new Triangle(measure);
}
}
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2001-2022, C# Key | Tuesday 16 November 2021 | Next |
|