Adding Properties to Classes


Developers normally don't make fields in classes public. There are three main reasons why developers don't like to give everyone access to fields.

The first reason is that developers often want to validate the value the developer is assigning to the field. For example, if a class called Person has a field called Age, a developer may try to write the following:

 Person p1 = new Person(); p1.Age = -99; 

However, a person's age can't be negative. If the Age field is public, there is nothing to prevent the developer from setting the field to incorrect values.

A second reason developers don't like to expose fields is that sometimes the information needs to be calculated based on the result of another field. For example, taking the same class, Person, suppose that in addition to the field Age the class also had a field called IsAdult (true or false). The value of the field IsAdult could be calculated based on the Age. If Age is > 18 for example, then IsAdult should be true, otherwise IsAdult would be false. If IsAdult were public, a developer could set IsAdult to something without taking into consideration Age.

The third main reason developers don't like to make a field public is that the field type may change in future releases. For example, it could be that a field called BouncedChecks begins as a type byte (0 through 255) and the bank later discovers that it needs to change the field's type to a long. If a field is made public, sometimes developers write their code assuming that the variable will contain a certain range of values. This makes it harder to change the type of the field later on.

For these reasons developers often use a technique called information hiding. It means setting the field to private and providing a pair of public functions, one to read the value, and one to set the value ( Figure 2.69 ). These functions are normally called SetX and GetX where X is the name of the field that the functions manipulate.

Figure 2.69 With information hiding you leave the field as private, then provide a function to set the value and one to read the value. This enables you to validate or calculate values before setting or reading the variable.
 class Person {    byte age;  public void SetAge(byte newage)  {      age = newage;    }  public byte GetAge()  {       return age;    } } class App {    void Task1()    {      Person p1 = new Person();      p1.age = 30; //***this is illegal      //***this is also illegal      Response.Write(p1.age);      //to set or get the age field you      //must go through the Set and Get      //functions      p1.  SetAge(45)  ;      Response.Write(p1.  GetAge()  );    } } 

A developer using the class would then be prevented from using the field directly. He or she would have to use the Set and Get function. This would enable the author of the class to validate, calculate, and even change the data type of the field later on ( Figure 2.70 ).

Figure 2.70 SetAge verifies that the age is greater than zero; if not, it sets the age to zero. IsAdult returns a calculated value based on the age.
 class Person {    byte age;    public void SetAge(byte newage)    {      //with a SetAge function you can      //now do validation of the value      //before storing it in the age      //field  if (newage < 0)   newage = 0;  age = newage;    }    public byte GetAge()    {      return age;    }    public bool IsAdult()    {      //information obtained from      //age field  return (age >= 18)  ; //returns true                             //if age is                             //greater than                             //or equal to                             //18    } } 

The only problem with adding Set and Get functions is that they aren't as nice to work with as working with fields. When reading the value you have to call Get and put parenthesis after the function name. To set the value you have to use Set and send the value in parenthesis, rather than using the name of the field and the = sign. That's where properties come in.

Properties are functions that behave like fields. With a property you declare a get function and a set function. The get and set enable you to do things like validations and calculating fields. To the user of the class however, it looks and feels as if they were using a field.

To add a property to the class:

  1. Start by following the syntax of adding a function. Type the return type, followed by a space and the name of the property, then stop. Don't add parentheses at the end of the property.

  2. Add an open curly bracket .

  3. Decide if the property will be read-only, write-only, or read-write.

  4. If it is read-only add a get handler only (step 5), if it is write-only add a set handler only (step 6), and if it is read-write add both a get handler and a set handler.

  5. Add a get handler as needed by writing the word get in a new line , followed by an open curly bracket, the code for the get handler and a close curly bracket. The code must at least return a value of the type of the property.

  6. Add a set handler as needed by writing the word set in a new line, followed by an open curly bracket, the code for the set handler and a close curly bracket. The variable name value is a reserved word that will store the value to which the user of the class is attempting to set the property.

  7. Add a close curly bracket ( Figure 2.71 ).

    Figure 2.71 Properties are functions that give the caller the feel of a field. You can add a set handler and a get handler to a property.
     class Person {    byte age;  public byte Age   {   get  {         return age;       }  set  {         //perform validation         if (value < 0)            value = 0;         age = value;       }  }   public bool Adult   {  //calculated read-only property  get  {         return (age >= 18);       }  }  } class App {    void ProgramCode()    {       Person p1 = new Person();  p1.Age = 30  ; //calls set portion                    //of property;                    //value keyword in                    //set contains 30       Response.Write(  p1.Age  ); //calls get                               //portion                               //of                               //property    } } 

graphics/tick.gif Tips

  • By default properties are private. This means they can only be used by code inside of the class. Until you learn about scope modifiers you can declare the properties as public if you wish to use them outside of the class ( Figure 2.72 ). A full explanation of scope modifiers requires an explanation of inheritance, found in Chapter 5, "Class Inheritance."

    Figure 2.72 Properties, like fields, are private by default; they can only be used inside the class in which they were defined. You can change the scope by adding a scope modifier in front of the declaration, like the word public.
     class NuclearPlant {    int _level;    int Level    {      get      {         return _level;      }      set      {         _level = value;      }    } } class App {    void Task1()    {      NuclearPlant np = new NuclearPlant();  np.Level = 50; //***this is illegal   //Level is private  } } 
  • Properties must have a get handler, a set handler, or both.

  • Read-only properties are properties that have a get handler but no set handler ( Figure 2.73 ).

    Figure 2.73 It's easy to add read-only properties. You just have to add a get handler to your property and not a set.
     class ToDoItem {    string item = "";    string description = "";  public string Item  {      //read-only property      //no set      get      {         return item;      }    }  public string Description  {      //read-only property      //no set      get      {         return description;      }    } } 
  • Write-only properties are properties that have a set handler but no get handler ( Figure 2.74 ). They aren't very common.

    Figure 2.74 Write-only properties aren't very common. One possible use would be to set the parts of a larger property. In this case you set the first name and the last name of an individual, but then read the person's full name and not each part.
     class Person {    string _firstName;    string _lastName;    //write-only property to set    //person's first name  public string FirstName  {      set      {         _firstName = value;      }    }    //write-only property to set    //person's last name  public string LastName  {      set      {         _lastName = value;      }    }    //read-only property to read    //full name    public string Name    {      get      {         return _firstName + _lastName;      }    } } 



C#
C# & VB.NET Conversion Pocket Reference
ISBN: 0596003196
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Jose Mojica

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net