Introduction to the Properties of a Class
Introduction to the Properties of a Class
Properties Fundamentals
Introduction
When you create a class, if you add a field (a member variable) that should be accessible only by other members of the same class, that is, if you want to "hide" a field from the outside world, you make it private. This technique makes sure that the clients of the class cannot directly change the value of the field.
If you create a field as private but still want other classes to access or get the value of such a field, you must then provide a mechanism that those class would use, like a door through which the external objects must pass access the field.
A property is a member of a class that plays an intermediary role to a field of the class. A property is used to "filter" access to a field of a class. Therefore, you start by declaring a (private (if you don't make it private, you may be deceiving the purpose of creating a property)) field. Here is an example:
public class Square
{
private double _side;
}
Obviously this private field cannot be accessed by an outside class. To let the outside classes access this variable, you would/can create a property.
Practical Learning: Introducing Properties
namespace Quadrilaterals1.Models { public class Square { private double s; public void Initialize(double side) { s = side; } } }
Creating a Property
There is no single syntax to create a property but there is a general starting formula. The beginning of a property resembles a field, but a property has a body like that of a class. Therefore, a property starts with the following formula:
options data-type property-name { }
You start with one or more options. As seen with fields, the primary option to apply to a property is an access level. Like a field, a property can be made to be accessed by only the members of the same class or by objects outside the class. This means that you can start a property with an access level of private, public, or internal. Most of the time, you will apply the public access level.
Like a field, a property must have a name. The name of a property follows the rules and policies of names of classes. This means that the name should resemble that of an object and start with an uppercase letter.
Like a field, a property must indicate its type, as its data type. Remember that, so far, we have applied the int, the string, and the double types. You can apply one of those to a property you are creating.
Like a class, a property must have a body, which is delimited by curly brackets immediately after its name. Based on these descriptions, a property can start as follows:
public class Square
{
// This is a new property
public double Side { }
}
To make it easy to read, each curly bracket can be created on its own line. Here is an example:
public class Square
{
public double Side
{
}
}
With regards to their roles, there are various types of properties.
Introduction to Property Readers
Overview
A property is referred to as read if its role is to make available the value of the member variable it represents. To create a read property, in the body of the property, type a contextual keyword(contextual means the word is a keyword only in some cases, depending on how it is being used) named get. Then create a body for that keyword, using the traditional curly brackets that delimit a section of code. Here is an example:
public class Square
{
public double Side
{
get {}
}
}
Once again, to make your code easy to read, each curly bracket can be written on its own line. The section that contains get and its curly bracket is referred to as the get section, or the get clause, or the getter.
The get section behaves like a section of code that produces a value. We already know that, to indicate that a section of code produces a value, in the body of the section of code, type the return keyword.
When a section of code produces a result, it must produce a value that is the same type as the data type indicated in its beginning. When it comes to a property, its get section must produce a value that is the same type indicated before its name. Therefore, in the body of the get clause, you must type return followed by a value. The simplest way consists of returning the field that corresponds to the property in the class. Here is an example:
public class Square { private double _side; public double Side { get { return _side; } } }
In the same way, you can create as many get properties as you judge necessary. Otherwise, in the body of a get clause, you can implement any behavior you want such as performing some operations before making the field's value available outside.
Practical Learning: Creating Property Readers
namespace Quadrilaterals1.Models
{
public class Square
{
private double s;
public void Initialize(double side)
{
s = side;
}
public double Side
{
get
{
return s;
}
}
public double Perimeter
{
get
{
return s * 4;
}
}
public double Area
{
get
{
return s * s;
}
}
}
}
Accessing a Property Reader
After creating a property, you can use it. We saw that, before using a class, you can create an instance of the class, which consists of declaring a variable of the class. We also saw that, to access a member of a class, type the name of the object, a period, and the desired member. This is also done to access a property.
Practical Learning: Accessing a Property Reader
using Quadrilaterals1.Models; using static System.Console; Square sqr = new Square(); WriteLine("====================================="); WriteLine("Enter the value to process the square"); Write("Side: "); double length = double.Parse(ReadLine()); sqr.Initialize(length); WriteLine("====================================="); WriteLine("Geometry - Square Summary"); WriteLine("-------------------------------------"); WriteLine("Side: {0}", sqr.Side); WriteLine("Perimeter: {0}", sqr.Perimeter); WriteLine("Area: {0}", sqr.Area); WriteLine("=====================================");
===================================== Enter the value to process the square Side: 148.97 ===================================== Geometry - Square Summary ------------------------------------- Side: 148.97 Perimeter: 595.88 Area: 22192.0609 ===================================== Press any key to close this window . . .
namespace PlanarCurves1.Models { public class Ellipse { private double _rad_, _Rad_; public double CalculateArea() { return _Rad_ * _rad_ * 3.14159265; } } }
An Expression-Bodied Property
We have learned to get a get clause of a property with a simple return value. Here is an example:
class Season
{
int temp;
public int MeanTemperature
{
get
{
return temp;
}
}
}
If you have a get clause that uses a simple return value, the C# language provides a simple way to implement such a clause. To do that, remove the curly brackets. Replace the return keyword with the => operator. Here is an example:
class Season
{
int temp;
public int MeanTemperature
{
get => temp;
}
}
Using the Body of a Property Reader
The body of a get clause of a property can be as complicated as you want, instead of simply returning its associated field. For example, you can declare a variable in the clause. You can decide to use such a variable or not. For example, you can involve such a variable in an expression. Here is an example:
public class Mattress { int _thk; public string Thickness { get { string pds = "pounds"; return _thk + " " + pds; } } }
Introduction to Property Writers
Introduction
Instead of retrieving the value of a field of a class, you may want external classes to be able to change the value of that member. A property is referred to as write if it can change (or write) the value of its corresponding field.
To create a write property, in the body of the property, type a contextual keyword named set. Create a body, which is delimited by curly brackets, for the property. Here is an example:
public class TimeSheet
{
public double Monday
{
set {}
}
}
Once again, to make your code easy to ready, you can write each curly bracket on its own line. Here is an example:
public class TimeSheet
{
public double Monday
{
set
{
}
}
}
A write property is used to pass a value from outside the class to a field of its class. Therefore, the least operation you can perform with a write property is to assign it a value that would be provided by the outside world. To support this, C# provides a contextual keyword named value. Assign this keyword to the set keyword. This can be done follows:
public class TimeSheet
{
private double _mon;
public double Monday
{
set
{
_mon = value;
}
}
}
In the same way, you can create as many write properties as you need.
Practical Learning: Creating Property Writers
namespace PlanarCurves1.Models
{
public class Ellipse
{
private double _rad_, _Rad_;
public double radius
{
set
{
_rad_ = value;
}
}
public double Radius
{
set
{
_Rad_ = value;
}
}
public double CalculateArea()
{
return _Rad_ * _rad_ * 3.14159265;
}
}
}
Accessing a Property Writer
To access a property writer, you must first declare a variable of its class and use the period operator. Like its name indicates, a property writer is used only to receive a value. This means that you can assign a value to a property writer, but, unlike a property reader, you can get the value of a property writer.
Practical Learning: Using a Property Writer
using PlanarCurves1.Models; using static System.Console; Ellipse els = new Ellipse(); WriteLine("========================================="); WriteLine("Enter the values to process the ellipse"); Write("Small Radius: "); double small = double.Parse(ReadLine()); Write("Large Radius: "); double large = double.Parse(ReadLine()); els.radius = small; els.Radius = large; WriteLine("========================================="); WriteLine("Geometry - Ellipse Summary"); WriteLine("-----------------------------------------"); WriteLine("Area: {0}", els.CalculateArea()); WriteLine("=========================================");
========================================= Enter the values to process the ellipse Small Radius: 167.97 Large Radius: 338.48 ========================================= Geometry - Ellipse Summary ----------------------------------------- Area: 178613.63408049085 ========================================= Press any key to close this window . . .
An Expression-Bodied Property Writer
A property writer is usually the best place to validate, to accept, or to reject a value that a property must deal with. This means that sometimes you will use to set clause to process a value. Still, many times, that clause will include only a single-line expression. In that case, you can omit the body of the clause. After the set keyword, type => and the expression that assigns value to the private field of the property. Here is an example:
public class Employee
{
private string code;
public string ContractIdentifier
{
set => code = value;
}
}
Introduction to Read/Write Properties
Introduction
In the above sections, we created properties with either get or set clauses. A property that has only a get clause is referred to as a read-only property. A property that has only a set clause is referred to as a write-only property.
Creating a Read/Write Property
A property is referred to as read/write if it can both receive values from the outside world and can provide values to the outside world. Therefore, a read/write property has both a get and a set sections.
To create a read/write property, you can/should first create a private field in the body of the class. Then create a get and a set clauses in the body of the property. In the body of the get section, return the field. In the body of the set section, assign the contextual value keyword to the field. Here is an example:
public class Square
{
double s;
public double Side
{
get
{
return s;
}
set
{
s = value;
}
}
}
By tradition, the get section is created before the set section, but that is not a rule. You can as well create a set section before a get section.
If you are using Microsoft Visual Studio, to generate a read/write property, right-click the section where you want to create the property and click Insert Snippet... Double-click Visual C#. In the list, double-click propfull:
Practical Learning: Creating Read-Write Properties
namespace PlanarCurves1.Models
{
public class Square
{
private double s;
public double Side
{
get
{
return s;
}
set
{
s = value;
}
}
public double Perimeter
{
get { return s * 4; }
}
public double Area
{
get { return s * s; }
}
}
}
Introduction to Initializing a Read-Write Property
There are various ways you can make sure that a property would get its values. We already saw that one way is to create an accessory method in the class, add a parameter of the type of the property and, in the body of the method, assign the argument to the property's field. Another way is to create a read/write property and stop there; then simply eventually let clients of the class assign a value to the property. Here is an example:
Employee empl = new Employee();
empl.ContractIdentifier = "HL-9480";
public class Employee
{
private string code;
public string ContractIdentifier
{
get { return code; }
set { code = value; }
}
}
Practical Learning: Initializing a Read-Write Property
using PlanarCurves1.Models;
using static System.Console;
Square sqr = new Square();
WriteLine("=====================================");
WriteLine("Enter the value to process the square");
Write("Side: ");
double length = double.Parse(ReadLine());
sqr.Side = length;
WriteLine("=====================================");
WriteLine("Geometry - Square Summary");
WriteLine("-------------------------------------");
WriteLine("Side: {0}", sqr.Side);
WriteLine("Perimeter: {0}", sqr.Perimeter);
WriteLine("Area: {0}", sqr.Area);
WriteLine("=====================================");
===================================== Enter the value to process the square Side: 1397.77 ===================================== Geometry - Square Summary ------------------------------------- Side: 1397.77 Perimeter: 5591.08 Area: 1953760.9729 ===================================== Press any key to close this window . . .
An Expression-Bodied Property
To simplify the code of a read/write property, you can create an expression-body for each. To do that, type the contextual keyword of the clause, followed by the => operator. For the get clause, add the field of the property. For the set clause, assign the contextual value keyword to the field of the property. Here is an example of a read/write property with expression bodies:
public class Employee { private string code; public string ContractIdentifier { get => code; set => code = value; } }
Practical Learning: Creating Expression-Bodied Properties
namespace PlanarCurves1.Models { public class Square { private double s; public double Side { get => s; set => s = value; } public double Perimeter { get => s * 4; } public double Area { get => s * s; } } }
===================================== Enter the value to process the square Side: 326.83 ===================================== Geometry - Square Summary ------------------------------------- Perimeter: 1307.32 Area: 106817.84889999998 ===================================== Press any key to close this window . . .
namespace TaxPreparation08.Models { public class IncomeTax { private double grsSal; public double GrossSalary { get { return grsSal; } set { grsSal = value; } } public double AmountAdded { get { double amt = 0.00; return amt; } } public double TaxFromIncome { get { return 0.00; } } public double TaxAmount { get { return AmountAdded + TaxFromIncome; } } public double NetPay { get { return GrossSalary - TaxAmount; } } } }
using TaxPreparation08.Models; using static System.Console; IncomeTax it = new IncomeTax(); WriteLine("============================================"); WriteLine(" - Idaho - State Income Tax -"); WriteLine("============================================"); WriteLine("Enter the information for tax preparation"); Write("Gross Salary: "); it.GrossSalary = double.Parse(ReadLine()); WriteLine("=============================================="); WriteLine("- DeltaX - Tax Preparation Services -"); WriteLine("----------------------------------------------"); WriteLine(" - Idaho - State Income Tax -"); WriteLine("=============================================="); WriteLine($"Gross Salary: {it.GrossSalary,8:f}"); WriteLine($"Amount Added: {it.AmountAdded,8:f}"); WriteLine($"Tax from Income: {it.TaxFromIncome,8:f}"); WriteLine("----------------------------------------------"); WriteLine($"Tax Amount: {it.TaxAmount,8:f}"); WriteLine($"Net Pay: {it.NetPay,8:f}"); WriteLine("==============================================");
============================================ - Idaho - State Income Tax - ============================================ Enter the information for tax preparation Gross Salary: 3255.85 ============================================== - DeltaX - Tax Preparation Services - ---------------------------------------------- - Idaho - State Income Tax - ============================================== Gross Salary: 3255.85 Amount Added: 0.00 Tax from Income: 0.00 ---------------------------------------------- Tax Amount: 0.00 Net Pay: 3255.85 ============================================== Press any key to close this window . . .
Properties and Conditional Statements
A Boolean Property
You can create a property of a Boolean type. To start, if you want to create a whole body for the property, first create a field that is of type bool and a body for the property. Here is an example:
public class Member { private bool isGood; // A Boolean property public bool Accepted { } }
If you want to create a read-only property, add only a get accessor that returns the Boolean field. Here is an example:
public class Member
{
private bool isGood;
public bool Accepted
{
get
{
return isGood;
}
}
}
If you want to create a write-only property, add only a set accessor. In its body, assign value to the Boolean field. Here is an example:
public class Member
{
private bool isGood;
public bool Accepted
{
set
{
isGood = value;
}
}
}
If you want to create a full read-write property, add both a get and a set accessors. Here is an example:
public class Member
{
private bool isGood;
public bool Accepted
{
get
{
return isGood;
}
set
{
isGood = value;
}
}
}
Once the Boolean property exists, you can use it like any other. For example, you can assign a value to it or get the value it holds. Of course, the value you assign must be set as true or false. Here are examples:
Member applicant = new Member();
// Setting a value to the Boolean property
applicant.Accepted = true;
public class Member
{
private bool isGood;
public bool Accepted
{
get
{
return isGood;
}
set
{
isGood = value;
}
}
}
A Conditional Statement in a Property Reader
A read-only property allows an object to provide values to other objects. Instead of just giving simple values, you can use a get property to perform meaningful calculations that are based on some conditions. Probably the simplest type of conditional statement you can use is if and related operators.
Practical Learning: Introducing Conditional Statements in Properties
namespace TaxPreparation08.Models { public class IncomeTax { private double grsSal; public double GrossSalary { get { return grsSal; } set { grsSal = value; } } public double AmountAdded { get { double amt = 0.00; // Idaho if ((grsSal is >= 0.00) && (grsSal is < 1_568)) { amt = 0.00; } else if ((grsSal is >= 1_568) && (grsSal is < 3_136)) { amt = 17.64; } else if ((grsSal is >= 3_136) && (grsSal is < 4_704)) { amt = 66.64; } else if ((grsSal is >= 4_704) && (grsSal is < 6_272)) { amt = 123.48; } else if ((grsSal is >= 6_272) && (grsSal is < 7_840)) { amt = 196.00; } else if ((grsSal is >= 7_840) && (grsSal is < 11_760)) { amt = 284.20; } else // if(grossSalary >= 11_760) { amt = 543.90; } return amt; } } public double TaxFromIncome { get { // Idaho if ((grsSal is >= 0.00) && (grsSal is < 1_568)) { return grsSal * 1.125 / 100.00; } else if ((grsSal is >= 1_568) && (grsSal is < 3_136)) { return (grsSal - 1_568) * 3.125 / 100.00; } else if ((grsSal is >= 3_136) && (grsSal is < 4_704)) { return (grsSal - 3_136) * 3.625 / 100.00; } else if ((grsSal is >= 4_704) && (grsSal is < 6_272)) { return (grsSal - 4_704) * 4.625 / 100.00; } else if ((grsSal is >= 6_272) && (grsSal is < 7_840)) { return (grsSal - 6_272) * 5.625 / 100.00; } else if ((grsSal is >= 7_840) && (grsSal is < 11_760)) { return (grsSal - 7_840) * 6.625 / 100.00; } else // if(grossSalary >= 11_760) { return (grsSal - 11_760) * 6.925 / 100.00; } } } public double TaxAmount { get { return AmountAdded + TaxFromIncome; } } public double NetPay { get { return GrossSalary - TaxAmount; } } } }
============================================ - Idaho - State Income Tax - ============================================ Enter the information for tax preparation Gross Salary: 3255.85 ============================================== - DeltaX - Tax Preparation Services - ---------------------------------------------- - Idaho - State Income Tax - ============================================== Gross Salary: 3255.85 Amount Added: 66.64 Tax from Income: 4.34 ---------------------------------------------- Tax Amount: 70.98 Net Pay: 3184.87 ============================================== Press any key to close this window . . .
namespace TaxPreparation08.Models { internal class IncomeTax { private double grsSal; public double GrossSalary { get => grsSal; set => grsSal = value; } public double AmountAdded { get { double amt = 0.00; // Idaho if ((grsSal is >= 0.00) && (grsSal is < 1_568)) { amt = 0.00; } else if ((grsSal is >= 1_568) && (grsSal is < 3_136)) { amt = 17.64; } else if ((grsSal is >= 3_136) && (grsSal is < 4_704)) { amt = 66.64; } else if ((grsSal is >= 4_704) && (grsSal is < 6_272)) { amt = 123.48; } else if ((grsSal is >= 6_272) && (grsSal is < 7_840)) { amt = 196.00; } else if ((grsSal is >= 7_840) && (grsSal is < 11_760)) { amt = 284.20; } else // if(grossSalary >= 11_760) { amt = 543.90; } return amt; } } public double TaxFromIncome { get { // Idaho if ((grsSal is >= 0.00) && (grsSal is < 1_568)) { return grsSal * 1.125 / 100.00; } else if ((grsSal is >= 1_568) && (grsSal is < 3_136)) { return (grsSal - 1_568) * 3.125 / 100.00; } else if ((grsSal is >= 3_136) && (grsSal is < 4_704)) { return (grsSal - 3_136) * 3.625 / 100.00; } else if ((grsSal is >= 4_704) && (grsSal is < 6_272)) { return (grsSal - 4_704) * 4.625 / 100.00; } else if ((grsSal is >= 6_272) && (grsSal is < 7_840)) { return (grsSal - 6_272) * 5.625 / 100.00; } else if ((grsSal is >= 7_840) && (grsSal is < 11_760)) { return (grsSal - 7_840) * 6.625 / 100.00; } else // if(grossSalary >= 11_760) { return (grsSal - 11_760) * 6.925 / 100.00; } } } public double TaxAmount { get => AmountAdded + TaxFromIncome; } public double NetPay { get => GrossSalary - TaxAmount; } } }
============================================ - Idaho - State Income Tax - ============================================ Enter the information for tax preparation Gross Salary: 6806.47 ============================================== - DeltaX - Tax Preparation Services - ---------------------------------------------- - Idaho - State Income Tax - ============================================== Gross Salary: 6806.47 Amount Added: 196.00 Tax from Income: 30.06 ---------------------------------------------- Tax Amount: 226.06 Net Pay: 6580.41 ============================================== Press any key to close this window . . .
A Conditional Statement in a Property Writer
A property writer allows external objects to provide a value to its corresponding field in the class. Because of this, and since it is through the writer that the external objects may change the value of the field, you can use the property writer to validate or reject a new value assigned to the field. Remember that the client objects of the class can only read the value of the field through the property reader. Therefore, there may be only little concern on that side. Here is an example:
public class TimeSheet
{
private double day;
public double Overtime
{
set
{
// A day contains only 24 hours. There is no way somebody can work over 24 hours.
if( day > 24 )
day = 0.00;
else
day = value;
}
}
}
Practical Learning: Ending the Lesson
|
|||
Previous | Copyright © 2001-2024, FunctionX | Sunday 30 April 2023, 15:34 | Next |
|