Lesson 3: Implementing Properties

Lesson 3: Implementing Properties

Properties are members of classes that expose member variables or objects. Properties have similarities to both fields and methods. Values are set and retrieved using the same syntax as fields: getting a value from a property or setting a value with a property actually calls a specialized method that carries out these functions. Properties can contain code that validates values before setting them or carries out any other function required by the application.

After this lesson, you will be able to

  • Explain how to implement properties

  • Describe how to create a read-only or write-only property

  • Explain what a default property or indexer is and how to create one

  • Explain how to expose a collection of objects as a property

Estimated lesson time: 30 minutes

Implementing Properties

Properties allow you to expose member values and objects in a more robust way than simply using fields. A property is essentially a specialized method that looks like a field. Property values are set and retrieved in the same manner as fields, as shown in the following example:

Visual Basic .NET

' Sets the value of the TextBox1.Text property TextBox1.Text = "Text Property" Dim myString As String ' Returns the value of TextBox1.Text and assigns it to myString myString = TextBox1.Text

Visual C#

// Sets the value of the TextBox1.Text property textBox1.Text = "Text property"; string myString; // Returns the value of TextBox1.Text and assigns it to myString myString = textBox1.Text;

At this level, a property looks and acts exactly like a field. However, the code behind a property is actually a bit more complex. Properties are divided into two special methods, a getter and a setter, which get and set the value of the property, respectively. The following example demonstrates a property declaration for a property called MyText:

Visual Basic .NET

' Creates a private local variable to store the value Private mText As String ' Implements the property Public Property MyText() As String Get ' Returns the value stored in the local variable Return mText End Get Set(ByVal Value As String) ' Set the value of the local variable mText = Value End Set End Property

Visual C#

// Creates a private local variable to store the value private string mText; // Implements the property public string MyText { get { // Returns the value stored in the local variable return mText; } set { // Sets the value of the local variable mText = value; } }

The Value (value) keyword is a special keyword used in the setter of a property. It always represents the value to which the property is being set. Properties can expose any kind of object, array, or collection. The value or object is usually stored in a private local variable (mText in the preceding example) and retrieved when the property is accessed.

Because it behaves in essentially the same manner as a field, the preceding example is a fairly trivial example of a property. A key advantage of properties is that you can provide additional code in the getter and setter of the property to perform calculations or validate the entry. The following example demonstrates how to create a property where the value is validated before being set:

Visual Basic .NET

Private mLength As Integer Public Property Length() As Integer Get ' Returns the value stored in the local variable Return mLength End Get Set(ByVal Value As Integer) ' Validates that the value does not exceed the maximum value ' of 32 If Value > 32 Then MessageBox.Show(Value.ToString & _  " is too large a value for this property!") Else mLength = Value End If End Set End Property

Visual C#

private int mLength; public int Length { get { // Returns the value stored in the local variable return mLength; } set { // Validates that the value does not exceed the maximum value // of 32 if (value > 32) MessageBox.Show(value.ToString() +  " is too large a value for this property!"); else mLength = value; } }

To create a property

  1. Create a private member field or object to hold the value or object that will be returned by the property.

  2. Write the code for the property that will return the value.

  3. Add any validation code in the getter or the setter that is required for the property.

Read-Only and Write-Only Properties

Sometimes, you will need to implement a property that can return a value to the client but cannot be changed once the class is initialized. Infrequently, you might need to create a property that can be changed but not read. These properties are called read-only and write-only properties, respectively.

Creating Read-Only Properties

Read-only properties are created in a manner similar to regular properties. In Visual Basic .NET, the property must be marked with the ReadOnly keyword and the setter is omitted. In Visual C#, creating a read-only property is as simple as providing only a getter and omitting the setter from a property. The private variable that holds the property value is also usually marked ReadOnly (readonly) although this is not required. The following example demonstrates a read-only property:

Visual Basic .NET

Private ReadOnly mInt As Integer Public ReadOnly Property InstanceNumber() As Integer Get Return mInt End Get End Property

Visual C#

private readonly int mInt; public int InstanceNumber { get { return mInt; } }

Because the variable holding the data for the property is read-only, it cannot be set or changed in code. You must set an initial value for the variable in the constructor of the class or when the variable is initialized.

To create a read-only property

  1. Create a private member variable to hold the property value. This variable must be marked ReadOnly in Visual Basic .NET and readonly in Visual C#.

  2. Implement the property, supplying a getter but not a setter. In Visual Basic .NET, the property should also be marked ReadOnly.

  3. Set the value of the private member variable in the constructor of the class for which it is a member.

Write-Only Properties

Although used infrequently, it is possible to create properties that can be written to but not read by the client. You might implement a write-only property that controls localization properties of a form. When a different locale is set, code in the property executes to make the appropriate changes to the form, and there is no need to access the value of the property.

A write-only property is created in a manner analogous to a read-only property. If the value of the write-only property is to be stored, you will need to create a private member variable to hold it. The property itself is implemented as a regular property, but only a setter is supplied. The getter is omitted. In Visual Basic .NET, the property must be marked with the WriteOnly keyword.

To create a write-only property

  1. If needed, create a private member variable to hold the value of the write-only property.

  2. Implement your property supplying only a setter. In the setter, write any code that you want to execute when the property is set. In Visual Basic .NET, you must also mark the property with the WriteOnly keyword.

Parameterized Properties

Most properties you create will return a single value or object. In Visual Basic .NET, you can create properties that accept parameters when accessed. These properties usually expose a range, or array, of values. For example, a single Engine object might have several Cylinders. Rather than expose each one individually, you could create a Cylinder property that returned or set each cylinder based on a supplied parameter.

You implement a parameterized property the same as a normal property except that you declare the parameter in the property declaration. Then, in the getter and setter of the property, you write appropriate code to retrieve the appropriate value or object. The following example exposes an array of objects through a parameterized property:

Visual Basic .NET

' Creates the array to hold the property values Private mCylinders(7) As Cylinder Public Property Cylinders(ByVal i As Integer) As Cylinder Get ' Validates the property value If I > 7 Then MessageBox.Show("Property value out of range!") Exit Property End If ' If the object doesn't exist, it creates a new one If mCylinders(i) Is Nothing Then mCylinders(i) = New Cylinder() End If Return mCylinders(i) End Get Set(ByVal Value As Cylinder) ' Validates the property value If i > 7 Then MessageBox.Show("Property value out of range!") Exit Property End If mCylinders(i) = Value End Set End Property

Visual C# does not allow you to create parameterized properties except for the indexer. (See the next section.)

Default Properties and Indexers

In Visual Basic .NET, you can designate a default property for your component. A default property is always a parameterized property and is usually used to expose a range, an array, or a collection of values. Enabling a default property only makes sense if the primary purpose of the object is to contain and expose other objects. If you mark a property as default, you can use the property name interchangeably with the object name. Thus, the following code functions interchangeably:

Visual Basic .NET

' This example assumes that the Item property is the default ' property of the myCollection object myCollection.Item(2) = "Default properties!" myCollection(2) = "Default properties!"

Because you can use the object name without further qualification to access the default property, you can have only one default property per class. You implement a default property by using the Default keyword in the property declaration as follows:

Visual Basic .NET

Public Default Property Item(I As Integer) As String ' Property Implementation omitted End Property

In Visual C#, the indexer is the equivalent of a Visual Basic .NET default property. The indexer is a specialized property that allows you to expose a group of objects on the name of the object. The name used in the indexer code is always this, which indicates that the name of the object itself will be used to access the property. A sample implementation of a Visual C# indexer follows:

Visual C#

// Creates an array to store the values exposed by the indexer private int[] IntArray; // The index variable in brackets is used to retrieve the correct item public int this[int index] { get { return IntArray[index]; } set { IntArray[index] = value; } }

To create a default property in Visual Basic .NET

Create a parameterized property that returns an object based on the parameter. Use the Default keyword in the property declaration.

To create an indexer in Visual C#

Create a property named this, and designate an index variable for the property. Write code that returns the appropriate object based on the index.

Collection Properties

If your object exposes an undetermined number of objects of the same type, you can expose a collection of objects through a property. Exposing collections of objects as properties allows you to control access to your subordinate objects and validate assignments.

There are a few different ways to implement collection properties. How you choose to do so depends on the kind of functionality you need to implement. Simple collection properties can simply return the collection, allowing clients to add and remove members to the collection, as well as to use all of the collection s methods. Most likely, you would expose the collection as a read-only property to prevent the client from assigning the property to a new instance of the collection class itself. The objects in the collection still can be changed with the collection s own methods. An example of a simple collection property follows:

Visual Basic .NET

Private ReadOnly mWidgets As New System.Collections.ArrayList() Public ReadOnly Property Widgets() As System.Collections.ArrayList Get Return mWidgets End Get End Property

Visual C#

private readonly System.Collections.ArrayList mWidgets = new System.Collections.ArrayList(); public System.Collections.ArrayList Widgets { get { return mWidgets; } }

Although this approach is simple and allows you access to the collection s members, there is one significant problem. Most of the collection classes in the System.Collections namespace accept and return their members as objects, which means that any kind of type can be added or removed to the collection. Thus, there is no type checking when members are added to the collection, and retrieved members must be explicitly converted to the correct type. If you want to manage groups of differently typed objects in a single property, this approach will be adequate.

To create a simple collection property

Implement a read-only property that returns the collection.

For more robust collection properties, you should wrap your collection object in the property and provide explicit conversion and validation code within the property. Doing so allows you to access the collection members by index and control the types that are added to the collection. In Visual Basic .NET, you must implement a property of this type as a parameterized property. An example follows:

Visual Basic .NET

Private mWidgets As New System.Collections.ArrayList() Public Property Widget(I As Integer) As Widget Get Return CType(mWidgets(I), Widget) End Get Set(ByVal Value As Widget) mWidgets(I) = Value End Set End Property

Because Visual C# does not allow parameterized properties, you must implement a property of this type either as an indexer or as a pair of methods. An example of the latter follows:

Visual C#

private System.Collections.ArrayList mWidgets = new System.Collections.ArrayList(); public Widget GetWidget(int I) { return (Widget)mWidgets[I]; } public void SetWidget(int I, Widget Wid) { mWidgets[I] = Wid; }

This approach allows for properties that are strongly typed and exposes a collection of like-typed items. There are drawbacks, however. With this approach, you lose the ability to iterate through the collection using For Each Next (foreach), and any other methods of the property that you want to expose to the client must be wrapped as well. Additionally, the syntax concessions required in Visual C# might be unsuitable.

To create a strongly typed collection property

  • In Visual Basic .NET, create a parameterized property that returns a member of a private collection based on the index. Use the CType keyword to convert the object returned by the collection to the appropriate type.

  • In Visual C#, create a pair of methods that get and set the object at the appropriate index in a private collection. In the get method, explicitly convert the object returned by the collection to the appropriate type.

For properties that require an even stronger implementation, you can implement your own strongly typed collection by inheriting from the System.Collections.CollectionBase class. This class provides most of the background functionality collections require and allows you to provide your own implementations of the item property. With a strongly typed collection, you can expose the collection directly in the property (as shown in the preceding example) and still have access to all the collection functionality. The collection will only accept members of the type you specify and will incorporate any other functionality you require. Inheritance is discussed in detail in Chapter 4, including an exercise demonstration on how to create a strongly typed collection.

Lesson Summary

  • Properties allow you to expose member variables or objects and provide code to validate property values or perform other functions when the property is accessed. Read-only and write-only properties are useful for limiting the client s ability to read or write to your properties. Visual Basic .NET allows you to create properties that accept parameters and can expose a range of values.

  • A default property allows access to values exposed by a property without using the property name for qualification. Default properties must be parameterized properties. An indexer is the Visual C# equivalent of a default property.

  • Collection properties are used to expose groups of objects exposed by your classes. There are several ways to do this, but each method has advantages and drawbacks as follows:

    • A simple collection property can return a private member collection object, but this approach is the least robust.

    • A property can return an object and access a private member collection object by index. This approach is more robust, but presents some limitations in the usability of your class.

    • Implementing a strongly typed collection class is developmentally intensive, but provides the most robust method for exposing a strongly typed collection of classes.



MCAD(s)MCSD Self-Paced Training Kit(c) Developing Windows-Based Applications With Microsoft Visual Basic. Net a[.  .. ]0-316
MCAD(s)MCSD Self-Paced Training Kit(c) Developing Windows-Based Applications With Microsoft Visual Basic. Net a[. .. ]0-316
ISBN: 735619263
EAN: N/A
Year: 2003
Pages: 110

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