|
Accessories for Properties
|
|
A
property is a member of a class that plays an intermediary role to a field
of the class. For example, if you have a field of class
and that member represents the salary of an employee, a property can be
the "door" that other classes that need the salary
must present their requests to. As such, these external
classes cannot just change the salary or retrieve it as they wish. A
property can be used to validate their request, to reject or to accept
them.
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:
using System;
public class Square
{
private double _side;
}
public class Exercise
{
public static int Main()
{
return 0;
}
}
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.
To indicate that
you are creating a property, there is a
syntax you must follow. To start, you must create a member whose formula
resembles a method without the parentheses. Since or if the property will
be accessed by only by objects of the same program, you can mark it with
the internal keyword. If the property will be accessed by objects
of this and other programs, you should mark it as public. Therefore, you would start a
property as follows:
public class Square
{
private double _side;
// This is a new property
public double Side
{
}
}
With regards to their role, there are two types of
properties.
|
Practical
Learning: Introducing Properties
|
|
- Start Microsoft Visual C# and create a Console
Application named DepartmentStore2
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to ShoppingItem and press Enter
- Change the content of the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class DepartmentStore
{
private long itemNo;
private string nm;
private string sz;
private decimal price;
}
}
|
- To create a property for each member variable, change the
ShoppingItem class as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class ShoppingItem
{
private string itemNo;
private string nm;
private string sze;
private decimal price;
// A property for the stock number of an item
public string ItemNumber
{
}
// A property for the name of an item
public string Name
{
}
// A property for size of a merchandise
public string Size
{
}
// A property for the marked price of an item
public decimal UnitPrice
{
}
}
}
|
- Save the file
|
A property is referred to as read if its role
is only 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
{
private double _side;
// This is a new property
public double Side
{
get
{
}
}
}
|
|
In the body of the get clause, you can implement the
behavior that would be used to make the field's value available
outside. The simplest way consists of just returning the corresponding
field. Here is an example:
public class Square
{
private double _side;
// This is a new property
public double Side
{
get
{
return _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 (only) a
read property, you should provide the users with the ability to primarily
specify the value of the member variable. To do this, you can create an
accessory method or a constructor for the class . Here is an example of
such a constructor:
public class Square
{
private double _side;
// This is a new property
public double Side
{
get
{
return _side;
}
}
public Square(double s)
{
_side = s;
}
}
Once a read property has been created, other classes can access it, for example they
can read its value as follows:
using System;
public class Square
{
private double _side;
// This is a new property
public double Side
{
get
{
return _side;
}
}
public Square(double s)
{
_side = s;
}
}
public class Exercise
{
public static int Main()
{
var sq = new Square(-25.55);
Console.WriteLine("Square Side: {0}", sq.Side);
return 0;
}
}
This would produce:
Square Side: -25.55
Press any key to continue...
We described a property as serving as a door from
outside to its corresponding field, preventing those outside
classes to mess with the member variable. Notice that the Square class was
given a negative value for the member variable, which is usually
unrealistic for the side of a square. In this case and others, while still
protecting the field as private, you can use the read property
to reset the value of the field or even to reject it. To provide
this functionality, you can create a conditional statement in the read
property to perform a checking process. Here is an example:
using System;
public class Square
{
private double _side;
// This is a new property
public double Side
{
get
{
// If the value given to the side is negative,
// then set it to 0
if (_side < 0)
return 0;
else
return _side;
}
}
public Square(double s)
{
_side = s;
}
}
public class Exercise
{
public static int Main()
{
var sq1 = new Square(-12.48);
var sq2 = new Square(25.55);
Console.WriteLine("First Square Characteristics");
Console.WriteLine("Side: {0}\n", sq1.Side);
Console.WriteLine("Second Square Characteristics");
Console.WriteLine("Side: {0}\n", sq2.Side);
return 0;
}
}
This would produce:
First Square Characteristics
Side: 0
Second Square Characteristics
Side: 25.55
|
Practical
Learning: Creating Property Readers
|
|
- To create read properties, change the contents of the
ShoppingStore.cs file as
follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class ShoppingItem
{
private long itemNo;
private string nm;
private string sz;
private decimal price;
// A property for the stock number of an item
public long ItemNumber
{
get
{
return itemNo;
}
}
// A property for the name of an item
public string Name
{
get
{
return nm;
}
}
// A property for size of a merchandise
public string Size
{
get
{
if( sz == "0" )
return "Unknown Size or Fits All";
else
return sz;
}
}
// A property for the marked price of an item
public decimal UnitPrice
{
get
{
return price;
}
}
// A constructor used to initialize an item
public ShoppingItem(long nbr,
string nme,
string siz,
decimal prc)
{
itemNo = nbr;
nm = nme;
sz = siz;
price = prc;
}
}
}
|
- Access the Program.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class Program
{
static void Main()
{
long number;
string name;
string size;
decimal price;
Console.WriteLine("/-/Arrington Department Store/-/");
Console.Write("Enter the Item #: ");
number = long.Parse(Console.ReadLine());
Console.Write("Enter the Item Name: ");
name = Console.ReadLine();
Console.Write("Enter the Item Size: ");
size = Console.ReadLine();
Console.Write("Enter the Unit Price: ");
price = decimal.Parse(Console.ReadLine());
ShoppingItem store = new ShoppingItem(number, name, size, price);
Console.WriteLine("\n================================");
Console.WriteLine("/-/Arrington Department Store/-/");
Console.WriteLine("--------------------------------");
Console.WriteLine("Customer Invoice");
Console.WriteLine("Item #: {0}", store.ItemNumber);
Console.WriteLine("Description: {0}", store.Name);
Console.WriteLine("Item Size: {0}", store.Size);
Console.WriteLine("Unit Price: {0:C}", store.UnitPrice);
Console.WriteLine("================================\n");
}
}
}
|
- Execute the program:
/-/Arrington Department Store/-/
Enter the Item #: 622805
Enter the Item Name: Black Leather Hand Bag
Enter the Item Size: Medium
Enter the Unit Price: 85.95
================================
/-/Arrington Department Store/-/
--------------------------------
Customer Invoice
Item #: 622805
Description: Black Leather Hand Bag
Item Size: Medium
Unit Price: $85.95
================================
Press any key to continue . . .
|
|
- Close the DOS window
|
In our Square class so far, we were using a
constructor to create a value for each of the necessary member variables. This meant that we had to always make
sure that we knew the value of the field when we declared an
instance of the class. Sometimes, this is not effective. For example, you
cannot just call a constructor in the middle of the program, that is after the
object has been declared, to assign a new value to the field. To
solve this kind of problem, you can provide another means of accessing
the field any time to change its value.
Besides, or 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. Continuing with our concern to hide a
field as private, you can create another type of property. A
property is referred to as write if it can change (or write) the value of
its corresponding field.
|
|
To create a write property, type the set keyword
followed by the curly bracket delimiters. Here is an example:
public class Square
{
private double _side;
// This is a new property
public double Side
{
set
{
}
}
}
The minimum assignment 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 Square
{
private double _side;
// This is a new property
public double Side
{
set
{
_side = value;
}
}
}
As you see, clients of a class can change the
corresponding field of a member variable through the property writer. Based on
this relationship, it is not unusual for a client of a class to make an
attempt to "mess" with a field. For example, an
external object can assign an invalid value to a member variable. Consider
the following program:
using System;
public class Square
{
public double _side;
// This is a new property
public double Side
{
set
{
_side = value;
}
}
public Square()
{
_side = 0;
}
public Square(double s)
{
_side = s;
}
public double Perimeter()
{
return _side * 4;
}
public double Area()
{
return _side * _side;
}
}
public class Exercise
{
public static int Main()
{
var sq1 = new Square();
var sq2 = new Square();
sq1._side = -12.48;
sq2._side = 25.55;
Console.WriteLine("First Square Characteristics");
Console.WriteLine("Side: {0}", sq1._side);
Console.WriteLine("Perimeter: {0}", sq1.Perimeter());
Console.WriteLine("Area: {0}\n", sq1.Area());
Console.WriteLine("Second Square Characteristics");
Console.WriteLine("Side: {0}", sq2._side);
Console.WriteLine("Perimeter: {0}", sq2.Perimeter());
Console.WriteLine("Area: {0}", sq2.Area());
return 0;
}
}
This would produce:
First Square Characteristics
Side: -12.48
Perimeter: -49.92
Area: 155.7504
Second Square Characteristics
Side: 25.55
Perimeter: 102.2
Area: 652.8025
Press any key to continue...
Because of this, and since it is through the writer
that the external objects would change the value of the member variable,
you can use the write property, rather than the reader, 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 read property. Therefore, there may be only little concern on
that side.
|
If you create a property that has only a set section,
the property is referred to as write-only because the other classes can only assign it a value (or write a value to it). If you
create a property that has both a get and a set sections, its
corresponding member variable can receive new values from outside the
class and the member variable can provide its values to clients of the
class. Such a property is referred to as read/write.
|
|
|
Practical
Learning: Creating Property Writers
|
|
- To create property writers and complete the program, change the
content of the ShoppingItem.cs file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class ShoppingItem
{
private long itemNo;
private string nm;
private string sz;
private decimal price;
// A property for the stock number of an item
public long ItemNumber
{
get
{
return itemNo;
}
set
{
if (itemNo <= 0)
itemNo = 0;
else
itemNo = value;
}
}
// A property for the name of an item
public string Name
{
get
{
return nm;
}
set
{
if (nm == "")
nm = "Item no Description";
else
nm = value;
}
}
// A property for size of a merchandise
public string Size
{
get
{
if( sz == "0" )
return "Unknown Size or Fits All";
else
return sz;
}
set
{
sz = value;
}
}
// A property for the marked price of an item
public decimal UnitPrice
{
get
{
return price;
}
set
{
if (price < 0)
price = 0.00M;
else
price = value;
}
}
public static ShoppingItem Read()
{
ShoppingItem shop = new ShoppingItem();
Console.Write("Item #: ");
shop.itemNo = long.Parse(Console.ReadLine());
Console.Write("Item Name: ");
shop.Name = Console.ReadLine();
Console.Write("Item Size (Enter 0 if unknown): ");
shop.Size = Console.ReadLine();
Console.Write("Unit Price: ");
shop.UnitPrice = decimal.Parse(Console.ReadLine());
return shop;
}
public static void Write(ShoppingItem item)
{
Console.WriteLine("Item #: {0}", item.ItemNumber);
Console.WriteLine("Description: {0}", item.Name);
Console.WriteLine("Item Size: {0}", item.Size);
Console.WriteLine("Unit Price: {0:C}", item.UnitPrice);
}
}
}
|
- Access the Program.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class Program
{
static void Main()
{
Console.WriteLine("/-/Arrington Department Store/-/");
Console.Write("Enter the following pieces of ");
Console.WriteLine("information about the sale item");
ShoppingItem saleItem = ShoppingItem.Read();
Console.WriteLine("\n================================");
Console.WriteLine("/-/Arrington Department Store/-/");
Console.WriteLine("--------------------------------");
ShoppingItem.Write(saleItem);
}
}
}
|
- Execute the program. Here is an example:
/-/Arrington Department Store/-/
Enter the following pieces of
information about the sale item
Item #: 114888
Item Name: North Hook Alpine Jacket
Item Size (Enter 0 if unknown): Large
Unit Price: 275.95
================================
/-/Arrington Department Store/-/
--------------------------------
Item #: 114888
Description: North Hook Alpine Jacket
Item Size: Large
Unit Price: $275.95
Press any key to continue . . .
|
|
- Close the DOS window
You can create a property as a Boolean type. To do this,
first specify its data type as bool. When treating the property, make
sure its get accessory returns a Boolean type. A Boolean property is not
like the other regular properties. It must specify its value as true or false.
As done for Boolean methods, a Boolean property must produce only a true or
false value.
|
Properties of External Classes
|
|
|
Properties and Enumerations |
|
An enumeration is a technique of creating data type that
mimics an integer. After creating it, you can treat it as a pseudo data type. You can declare a variable from it, you can pass it as an
argument, and you can return it from a method. Based on these characteristics,
you can create a property that is based on an enumeration.
To create an enumeration property, you use the same
formula as one of the primitive data types we have used previously. Keep it mind
that the property is of the type of an enumeration. This means that you cannot
request its value like that of a primitive type and, when manipulating it, you
must process it appropriately.
|
Practical
Learning: Creating an Enumeration Property |
|
- Access the ShoppingStore.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
public enum ItemCategory
{
Unspecified,
Women,
Men,
Girls,
Boys,
Babies
}
class ShoppingItem
{
private long itemNo;
private ItemCategory cat;
private string nm;
private string sz;
private decimal price;
// A property for the stock number of an item
public long ItemNumber
{
get
{
return itemNo;
}
set
{
if (itemNo <= 0)
itemNo = 0;
else
itemNo = value;
}
}
// A property for the category of item
public ItemCategory Category
{
get
{
return cat;
}
set
{
cat = value;
}
}
// A property for the name of an item
public string Name
{
get
{
return nm;
}
set
{
if (nm == "")
nm = "Item no Description";
else
nm = value;
}
}
// A property for size of a merchandise
public string Size
{
get
{
if( sz == "0" )
return "Unknown Size or Fits All";
else
return sz;
}
set
{
sz = value;
}
}
// A property for the marked price of an item
public decimal UnitPrice
{
get
{
return price;
}
set
{
if (price < 0)
price = 0.00M;
else
price = value;
}
}
public static ShoppingItem Read()
{
int category = 0;
ShoppingItem shop = new ShoppingItem();
Console.Write("Item #: ");
shop.itemNo = long.Parse(Console.ReadLine());
Console.WriteLine("Store Items Categories");
Console.WriteLine("\t1. Women");
Console.WriteLine("\t2. Men");
Console.WriteLine("\t3. Girls");
Console.WriteLine("\t4. Boys");
Console.WriteLine("\t5. Babies");
Console.Write("Enter the Category: ");
category = int.Parse(Console.ReadLine());
if (category == 1)
shop.Category = ItemCategory.Women;
else if (category == 2)
shop.Category = ItemCategory.Men;
else if (category == 3)
shop.Category = ItemCategory.Girls;
else if (category == 4)
shop.Category = ItemCategory.Boys;
else if (category == 5)
shop.Category = ItemCategory.Babies;
else
shop.Category = ItemCategory.Unspecified;
Console.Write("Item Name: ");
shop.Name = Console.ReadLine();
Console.Write("Item Size (Enter 0 if unknown): ");
shop.Size = Console.ReadLine();
Console.Write("Unit Price: ");
shop.UnitPrice = decimal.Parse(Console.ReadLine());
return shop;
}
public static void Write(ShoppingItem item)
{
Console.WriteLine("Item #: {0}", item.ItemNumber);
Console.WriteLine("Category: {0}", item.Category);
Console.WriteLine("Description: {0}", item.Name);
Console.WriteLine("Item Size: {0}", item.Size);
Console.WriteLine("Unit Price: {0:C}", item.UnitPrice);
}
}
}
|
- Execute the application and test it. Here is an example:
/-/Arrington Department Store/-/
Enter the following pieces of
information about the sale item
Item #: 624008
Store Items Categories
1. Women
2. Men
3. Girls
4. Boys
5. Babies
Enter the Category: 3
Item Name: Scotta Miniskirt
Item Size (Enter 0 if unknown): 11
Unit Price: 35.95
================================
/-/Arrington Department Store/-/
--------------------------------
Item #: 624008
Category: Girls
Description: Scotta Miniskirt
Item Size: 11
Unit Price: $35.95
Press any key to continue . . .
|
|
- Close the DOS window
Remember that, after creating a class, it becomes a data
type in its own right. We have seen that you could declare a variable from it,
you could pass it as argument, and you could return it from a method. As a
normal data type, a class can be validated. This means that its value can be
evaluated, rejected, or retrieved. Based on these characteristics of a class,
you can create a property from it.
To create a property that is based on a class, primarily
follow the same formulas we have applied to the other properties. The most
important aspect to remember is that the class is composite. That is, it is
(likely) made of fields of various types.
|
Practical
Learning: Creating a Property of a Class Type |
|
- Access the ShoppingItem.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
public enum ItemCategory
{
Unspecified,
Women,
Men,
Girls,
Boys,
Babies
}
class ShoppingItem
{
private long itemNo;
private ItemCategory cat;
private string nm;
private string sz;
private decimal price;
// A property for the stock number of an item
public long ItemNumber
{
get
{
return itemNo;
}
set
{
itemNo = value;
}
}
// A property for the category of item
public ItemCategory Category
{
get
{
return cat;
}
set
{
cat = value;
}
}
// A property for the name of an item
public string Name
{
get
{
return nm;
}
set
{
if (nm == "")
nm = "Item no Description";
else
nm = value;
}
}
// A property for size of a merchandise
public string Size
{
get
{
if (sz == "0")
return "Unknown Size or Fits All";
else
return sz;
}
set
{
sz = value;
}
}
// A property for the marked price of an item
public decimal UnitPrice
{
get
{
return price;
}
set
{
if (price < 0)
price = 0.00M;
else
price = value;
}
}
}
}
|
- To create a new class, in the Solution Explorer, right-click the name of
the project, position the mouse on Add and click Class...
- Set the Name to DepartmentStore and click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class DepartmentStore
{
private int qty;
private ShoppingItem itm;
public int Quantity
{
get { return qty; }
set
{
if (qty <= 0)
qty = 0;
else
qty = value;
}
}
public ShoppingItem SaleItem
{
get { return itm; }
set
{
if (itm == null)
{
itm.ItemNumber = 0;
itm.Category = ItemCategory.Unspecified;
itm.Name = "Unknown";
itm.Size = "0";
itm.UnitPrice = 0.00M;
}
else
itm = value;
}
}
public DepartmentStore()
{
itm = new ShoppingItem();
}
public void ProcessOrder()
{
int category;
Console.WriteLine("/-/Arrington Department Store/-/");
Console.WriteLine("Enter the following pieces of");
Console.WriteLine("information about the sale item");
Console.Write("Item #: ");
itm.ItemNumber = long.Parse(Console.ReadLine());
Console.WriteLine("Store Items Categories");
Console.WriteLine("\t1. Women");
Console.WriteLine("\t2. Men");
Console.WriteLine("\t3. Girls");
Console.WriteLine("\t4. Boys");
Console.WriteLine("\t5. Babies");
Console.Write("Enter the Category: ");
category = int.Parse(Console.ReadLine());
if (category == 1)
itm.Category = ItemCategory.Women;
else if (category == 2)
itm.Category = ItemCategory.Men;
else if (category == 3)
itm.Category = ItemCategory.Girls;
else if (category == 4)
itm.Category = ItemCategory.Boys;
else if (category == 5)
itm.Category = ItemCategory.Babies;
else
itm.Category = ItemCategory.Unspecified;
Console.Write("Item Name: ");
itm.Name = Console.ReadLine();
Console.Write("Item Size (Enter 0 if unknown): ");
itm.Size = Console.ReadLine();
Console.Write("Unit Price: ");
itm.UnitPrice = decimal.Parse(Console.ReadLine());
Console.Write("How many samples of ");
Console.Write(itm.Name);
Console.Write(": ");
qty = int.Parse(Console.ReadLine());
}
public void DisplayReceipt()
{
decimal totalPrice = itm.UnitPrice * Quantity;
Console.WriteLine("\n================================");
Console.WriteLine("/-/Arrington Department Store/-/");
Console.WriteLine("--------------------------------");
Console.WriteLine("Item #: {0}", itm.ItemNumber);
Console.WriteLine("Category: {0}", itm.Category);
Console.WriteLine("Description: {0}", itm.Name);
Console.WriteLine("Item Size: {0}", itm.Size);
Console.WriteLine("Unit Price: {0:C}", itm.UnitPrice);
Console.WriteLine("Quantity: {0}", Quantity);
Console.WriteLine("Total Price: {0:C}\n", totalPrice);
Console.WriteLine("\n================================");
}
}
}
|
- Access the Program.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DepartmentStore2
{
class Program
{
static void Main()
{
DepartmentStore store = new DepartmentStore();
store.ProcessOrder();
store.DisplayReceipt();
}
}
}
|
- Execute the application and test it. Here is an example:
/-/Arrington Department Store/-/
Enter the following pieces of
information about the sale item
Item #: 444412
Store Items Categories
1. Women
2. Men
3. Girls
4. Boys
5. Babies
Enter the Category: 1
Item Name: Stretch Cotton Shirt
Item Size (Enter 0 if unknown): 14
Unit Price: 55.95
How many samples of Stretch Cotton Shirt: 2
================================
/-/Arrington Department Store/-/
--------------------------------
Item #: 444412
Category: Women
Description: Stretch Cotton Shirt
Item Size: 14
Unit Price: $55.95
Quantity: 2
Total Price: $111.90
================================
Press any key to continue . . .
|
 |
- Close the DOS window
|
|