Introduction to the Properties of a Class
Introduction to the Properties of a Class
Fundamentals of Properties
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 can make it private. This technique makes sure that the clients of the class cannot directly change the value of the field. Here is an example:
public class Square
{
private decimal _side;
}
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 classes would use. 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.
Practical Learning: Introducing Properties
public class Square { private decimal s; public Square(decimal 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:
access-level data-type property-name { }
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 must 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 start with an uppercase letter. 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 decimal 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 decimal Side
{
}
}
With regards to their roles, there are various types of properties.
Types of Properties
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 the get keyword and create a body for the keyword, using the traditional curly brackets that delimit a section of code. Here is an example:
public class Square
{
public decimal 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 curcly bracket is referred to as the get section, or the get clause, or the getter.
The get section behaves like a method that returns a value. The returned value must be of the data type of the property. Therefore, in the body of the get clause, you must return a value using the return keyword. The simplest way consists of returning the field that corresponds to the property in the class. Here is an example:
public class Square
{
private decimal _side;
public decimal Side
{
get
{
return _side;
}
}
}
Otherwise, in the body of the get clause, you can implement any behavior you want, such as performing some operations before making the field's value available outside. Since the private field is a member of the class, you can also use the this object to access it. Here is an example:
public class Square
{
private decimal _side;
public decimal Side
{
get
{
return this._side;
}
}
}
A read property is also referred to as read-only property because the clients of the class can only retrieve the value of the property but they cannot change it. Therefore, if you create a read property, you should provide the users with the ability to primarily specify the value of the field it represents. To do this, you can create an accessory method or a constructor for the class. The method or constructor should use a parameter that is the same type as the property and field. In the body of the method or constructor, assign the parameter to the field. This can be done as follows:
public class Square
{
private decimal _side;
public decimal Side
{
get
{
return this._side;
}
}
public Square(decimal s)
{
this._side = s;
}
}
Once a read property has been created, other classes can access it, for example they can read its value.
Practical Learning: Creating Read-Only Properties
public class Square
{
private decimal s;
public Square(decimal side)
{
s = side;
}
public decimal Side
{
get { return s; }
}
public decimal Perimeter
{
get { return s * 4M; }
}
public decimal Area
{
get { return s * s; }
}
}
<!DOCTYPE html> <html> <head> <title>Geometry - Square</title> </head> <body> @{ Square flat = new Square(0.00M); if (IsPost) { decimal side = Request["txtSide"].AsDecimal(); flat = new Square(side); } } <div align="center"> <h2>Geometry - Square</h2> <form name="frmGeometry" method="post"> <table> <tr> <td style="width: 120px; font-weight: bold">Side:</td> <td><input type="text" name="txtSide" value="@flat.Side" /></td> <td><input type="submit" name="txtSubmit" value=Calculate /></td> </tr> <tr> <td style="font-weight: bold">Perimeter:</td> <td><input type="text" name="txtPerimeter" value=@flat.Perimeter /></td> <td> </td> </tr> <tr> <td style="font-weight: bold">Area:</td> <td><input type="text" name="txtArea" value=@flat.Area /></td> <td> </td> </tr> </table> </form> </div> </body> </html>
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 the set keyword and create a curly-bracket delimited body for it. Here is an example:
public class TimeSheet
{
public decimal 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 the value contextual keyword (contextual means the word is a keyword only in some cases, depending on how it is being used). Here is an example:
public class TimeSheet
{
public decimal Monday
{
set
{
mon = value;
}
}
}
In the same way, you can create as many write properties as you need.
Practical Learning: Creating Write-Only Properties
body { margin: 0; background-color: #ffffff; } h1 { font-size: 1.58em; } h2 { font-size: 1.28em; } .container { margin: auto; width: 300px; } table { width: 100%; } .emphasize { font-weight: bold; } .left-col { width: 120px; } h1, h2 { text-align: center; }
public class TimeSheet { private decimal mon; private decimal tue; private decimal wed; private decimal thu; private decimal fri; public decimal Monday { set { mon = value; } } public decimal Tuesday { set { tue = value; } } public decimal Wednesday { set { wed = value; } } public decimal Thursday { set { thu = value; } } public decimal Friday { set { fri = value; } } public decimal TimeWorked { get { return mon + tue + wed + thu + fri; } } }
<!DOCTYPE html> <html> <head> <title>Fun Department Store</title> <link rel="stylesheet" type="text/css" href="~/Content/Site.css" /> </head> <body> @{ TimeSheet ts = new TimeSheet(); decimal monday = 0M; decimal tuesday = 0M; decimal wednesday = 0M; decimal thursday = 0M; decimal friday = 0M; if (IsPost) { monday = Request["txtMonday"].AsDecimal(); tuesday = Request["txtTuesday"].AsDecimal(); wednesday = Request["txtWednesday"].AsDecimal(); thursday = Request["txtThursday"].AsDecimal(); friday = Request["txtFriday"].AsDecimal(); ts.Monday = monday; ts.Tuesday = tuesday; ts.Wednesday = wednesday; ts.Thursday = thursday; ts.Friday = friday; } } <div class="container"> <h2>Fun Department Store</h2> <h3 style="text-align: center">- Time Sheet -</h3> <form name="frmPayroll" method="post"> <table> <tr> <td style="width: 120px; font-weight: bold">Monday:</td> <td><input type="text" name="txtMonday" value="@monday" /></td> <td> </td> </tr> <tr> <td style="width: 120px; font-weight: bold">Tuesday:</td> <td><input type="text" name="txtTuesday" value="@tuesday" /></td> <td> </td> </tr> <tr> <td style="font-weight: bold">Wednesday:</td> <td><input type="text" name="txtWednesday" value="@wednesday" /></td> <td> </td> </tr> <tr> <td style="font-weight: bold">Thursday:</td> <td><input type="text" name="txtThursday" value="@thursday" /></td> <td> </td> </tr> <tr> <td style="font-weight: bold">Friday:</td> <td><input type="text" name="txtFriday" value="@friday" /></td> <td><input type="submit" name="txtSubmit" value=Calculate /></td> </tr> <tr> <td style="font-weight: bold">Time Worked:</td> <td><input type="text" name="txtTimeWorked" value="@ts.TimeWorked" /></td> <td> </td> </tr> </table> </form> </div> </body> </html>
Read/Write Properties
A property is referred to as read/write if it can both receive values from the outside world and it can provide values to the outside world. A read/write property has both a get and a set sections.
To create a read/write property, create a get and a set clauses in the body of the property. If you are using Microsoft Visual Studio, 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
public class Square
{
private decimal s;
public Square(decimal side)
{
s = side;
}
public decimal Side
{
get
{
return s;
}
set
{
s = value;
}
}
public decimal Perimeter
{
get { return s * 4; }
}
public decimal Area
{
get { return s * s; }
}
}
Automatic Properties
Introduction
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 decimal Width { get; set; }
}
Practical Learning: Introducing Automatic Properties
public class Element { public string Symbol { get; set; } public string ElementName { get; set; } public int AtomicNumber { get; set; } public decimal AtomicWeight { get; set; } }
Initializing an Automatic Property
To initialize an automatic property, you can create a constructor that uses a parameter for the property. In the body of the constructor, assign the argument to the property. Here is an example:
public class Element
{
public int AtomicNumber { get; set; }
public Element(int number)
{
AtomicNumber = number;
}
}
In the same way, if you want the property to be initialized with any value of your choice, you don't have to include a corresponding value in the constructor. Instead, in the body of the constructor, you can assign any value you want. Here is an example:
public class Element
{
public int AtomicNumber { get; set; }
public Element(int number)
{
AtomicNumber = 12;
}
}
Practical Learning: Initializing Automatic Properties
public class Element
{
public string Symbol { get; set; }
public string ElementName { get; set; }
public int AtomicNumber { get; set; }
public decimal AtomicWeight { get; set; }
public Element()
{
Symbol = "O";
AtomicNumber = 8;
ElementName = "Oxygen";
AtomicWeight = 15.999M;
}
}
<!DOCTYPE html> <html> <head> <title>Chemistry - Oxygen</title> </head> <body> @{ Element h = new Element(); } <div align="center"> <h2>Chemistry - Oxygen</h2> <form name="frmChemistry" method="post"> <table> <tr> <td style="width: 120px; font-weight: bold">Symbol:</td> <td><input type="text" name="txtSymbol" value=@h.Symbol /></td> </tr> <tr> <td style="font-weight: bold">Element Name:</td> <td><input type="text" name="txtElementName" value=@h.ElementName /></td> </tr> <tr> <td style="font-weight: bold">Atomic Number:</td> <td><input type="text" name="txtAtomicNumber" value=@h.AtomicNumber /></td> </tr> <tr> <td style="font-weight: bold">Atomic Weight:</td> <td><input type="text" name="txtAtomicWeight" value=@h.AtomicWeight /></td> </tr> </table> </form> </div> </body> </html>
Assigning a Default Value to an Automatic Property
Instead of initializing an automatic property in a constructor, you can assign the desired value after the curly brackets of the property. Here is an example:
public class Element
{
public int AtomicNumber { get; set; } = 12;
}
Practical Learning: Automatically Initializing Properties
public class Element { public string Symbol { get; set; } = "F"; public string ElementName { get; set; } = "Fluorine"; public int AtomicNumber { get; set; } = 9; public decimal AtomicWeight { get; set; } = 18.998403163m; }
<!DOCTYPE html> <html> <head> <title>Chemistry - Fluorine</title> </head> <body> @{ Element h = new Element(); } <div align="center"> <h2>Chemistry - Fluorine</h2> . . . </div> </body> </html>
Automatic Read-Only Properties
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 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; }
}
As we saw previously, if you want to initialize a read-only property, you can create a constructor that uses its corresponding type. Then, in the body of the constructor, assign the argument to the property. Here is an example:
public class Depreciation
{
public decimal Cost { get; }
public Depreciation(decimal cost)
{
Cost = cost;
}
}
As an alternative and as we saw for automatic read-write properties, to initialize a read-only property, instead of using a constructor, after the curcly brackets of the property, assign the desired default value. Here is an example:
public class Depreciation
{
public decimal Cost { get; } = 10000;
}
Practical Learning: Creating Automatic Read-Only Properties
static public class Calculations { static public decimal Subtract(decimal a, decimal b) { return a - b; } public static decimal Divide(decimal a, decimal b) { return a / b; } }
public class Depreciation { public decimal Cost { get; } public decimal SalvageValue { get; } public int Life { get; } public Depreciation(decimal cost, decimal value, int length) { Cost = cost; SalvageValue = value; Life = length; } public decimal Calculate() { decimal numerator = Calculations.Subtract(Cost, SalvageValue); return Calculations.Divide(numerator, Life); } }
<!DOCTYPE html> <html> <head> <title>Depreciation - Straight-Line Method</title> </head> <body> @{ Depreciation deprec = new Depreciation(0M, 0M, 1); if (IsPost) { decimal cost = Request["txtCost"].AsDecimal(); decimal value = Request["txtSalvageValue"].AsDecimal(); int life = Request["txtEstimatedLife"].AsInt(); deprec = new Depreciation(cost, value, life); } } <div align="center"> <h2>Depreciation - Straight-Line Method</h2> <form name="frmGeometry" method="post"> <table> <tr> <td style="width: 120px; font-weight: bold">Side:</td> <td><input type="text" name="txtCost" value=@deprec.Cost /></td> <td> </td> </tr> <tr> <td style="width: 120px; font-weight: bold">Salvage Value:</td> <td><input type="text" name="txtSalvageValue" value=@deprec.SalvageValue /></td> <td> </td> </tr> <tr> <td style="font-weight: bold">Estimated Life:</td> <td><input type="text" name="txtEstimatedLife" style="width: 60px;" value=@deprec.Life />Years</td> <td><input type="submit" name="txtSubmit" value=Calculate /></td> </tr> <tr> <td style="font-weight: bold">Depreciation:</td> <td><input type="text" name="txtDepreciation" value=@deprec.Calculate() /></td> <td> </td> </tr> </table> </form> </div> </body> </html>
static public class Calculations { static public decimal Subtract(decimal a, decimal b) => a - b; public static decimal Divide(decimal a, decimal b) => a / b; }
using static Calculations; public class Depreciation { public decimal Cost { get; } public decimal SalvageValue { get; } public int Life { get; } public Depreciation(decimal cost, decimal value, int length) { Cost = cost; SalvageValue = value; Life = length; } public decimal Calculate() => Divide(Subtract(Cost, SalvageValue), Life); }
Topics on Properties
Static Properties
A property can be made static. One option is to create the property in a normal class. The corresponding field must also be static. Here is an example:
public class Square { static decimal s; public Square() { } public static decimal Side { get { return s; } set { s = value; } } public decimal Perimeter { get { return s * 4; } } public decimal Area { get { return s * s; } } }
Most of the time, a static property is created as a member of a static class, in which case all members are static. After creating a static property, to access it outside the class, you don't need an instance of the class. You apply it directly to the name of the class. Here is an example:
public class Geometry { private void Create() { decimal side = 973.24; Square.Side = side; } } public static class Square { static decimal s; static Square() { } public static decimal Side { get { return s; } set { s = value; } } static public decimal Perimeter { get { return s * 4; } } public static decimal Area { get { return s * s; } } }
A Class as a Property
Remember that, after creating a class, it becomes a data type in its own right. As a normal data type, you can create a property from it.
To create a property that is based on a class, you primarily follow the same formulas we have applied to the other properties. This means that you can first create a field that is the type of the class of the intended property. You can then create the property with its get and set clauses. Here is an example:
public class Circle
{
}
public class Cylinder
{
private Circle round;
public Cylinder(Circle circ)
{
round = circ;
}
public Circle Base
{
get
{
return round;
}
set
{
round = value;
}
}
}
Most of the classes handle their own processing and validations. This means that most class-based properties are ready to simply be used. In such cases, you can create the property as an automatic property.
When you create a class-based property, probably the most important aspect to know is that the class is composite. That is, it is (likely) made of fields of various types. The property you are creating has access to the public (and internal) members of that class. You can directly access those members from the name of the property. Here is an example of a class that uses properties of class types:
public class Rectangle { public Rectangle(decimal wide, decimal high) { Width = wide; Height = high; } public decimal Width { get; set; } public decimal Height { get; set; } public decimal Area { get { return Width * Height; } } public decimal Perimeter { get { return (Width + Height) * 2; } } } public class Circle { public Circle(decimal radius) { Radius = radius; } public decimal Radius { get; set; } public decimal Area { get { return Radius * Radius * 3.14; } } public decimal Diameter { get { return Radius * 2; } } public decimal Circumferemce { get { return Diameter * 3.14; } } } public class Cylinder { public Cylinder(decimal radius, decimal height) { Base = new Circle(radius); Lateral = new Rectangle(Base.Circumferemce, height); } public Circle Base { get; set; } public Rectangle Lateral { get; set; } public decimal BaseArea { get { return Base.Area; } } public decimal LateralArea { get { return Lateral.Area; } } public decimal Volume { get { return BaseArea * Lateral.Height; } } }
Practical Learning: Ending the Lesson
|
||
Previous | Copyright © 2001-2019, FunctionX | Next |
|