Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Casting Reference Types in Visual Basic .NET : Page 3

Casting objects (.NET reference types) is an important technique when attempting to aggregate any collection of dissimilar object instances. Understanding how casting works also illustrates the value of using interfaces when defining classes.

Casting and Interfaces
You may wonder what use all of this is to you as a developer. The ability to reduce the members of a class to a subset—a subset that it may share with other, different classes—allows you to work with a collection of such objects. As you know, to create the simplest of collections, an array, you must define the type of elements the array will be able to store. You may wish to store a group of different objects to an array, which would be impossible if you could not cast the objects into a common type.

For example, assume you have an Employee class with subclasses such as SalesPerson, Supervisor, CustomerServiceRep, and so on. You may wish to create an array-based collection of a group of these objects with access to a common Employee class member such as a CurrentPayRate() property. However, in their "native" state, this would not be possible. You cannot do the following:

Dim Employees() As SalesPerson Or Supervisor_ Or CustomerServiceRep

However, you can do this:

Dim Employees(2) As Employee Employees(0) = CType(New _ SalesPerson(),"Employee") Employees(1) = CType(New _ Supervisor(),"Employee") Employees(2) = CType(New _ CustomerServiceRep(),"Employee") Dim i As Integer For i = 0 to UBound(Employees) Console.WriteLine("Current rate of pay is "_ + Employees(i).CurrentPayRate.ToString() End For

This works fine for a group of objects that may be based on the same superclass, or otherwise share a common ancestor. However, there may be disparate classes that you need to process as a collection, or pass as an argument to a method that do not share any common ancestor other than System.Object. How can you use casting to work around this? You can indeed cast such objects as a System.Object then recast them to their native types, but this may require more knowledge about the objects than you may possess in a given situation. Interfaces, however, are tailor-made to address this issue.

Any group of object classes can implement a common interface, and such an interface can be used in an object collection or passed as an argument by extracting the interface alone, using the CType() function to cast the object as it's interface.

You may have noticed in the Watercraft class that it implements the ITopSpeed interface. The code for this interface is as follows:

Interface ITopSpeed Property TopSpeed() As Integer End Interface

Each class that implements this interface has specific code to return a value from or store a value to a private field. Because the Watercraft class implements this interface, any derived class will inherit this interface. The Bicycle class and its derived class also implement the ITopSpeed interface, thus you can create an array to hold references to this interface and work with any members defined by this interface without regard to the fact that the interfaces may belong to vastly different classes. The code in Listing 2 shows how (in a very simple manner) this can be used:

Figure 3 shows the output from executing this code.

Figure 3: Using an interface reference to work with a collection of disparate objects.
It has always been important for programming languages to provide the ability to convert values from one type to another. .NET languages let you convert object references based on one class to another object reference that appears and behaves like an object based on another class.

If you understand and use casting, it is possible to usefully aggregate class instances.
If you understand and use casting it is possible to usefully aggregate class instances whether you want to access them as a collection or create generic black-box methods and functions that can accept any class instance cast as an object or an implemented interface. This could then re-cast the class instances back into their original type to access type members, or in the case of an interface, access the interface members directly.

For example, many intrinsic interfaces in the .NET Framework, such as IComparable.CompareTo() specify an argument of type Object, but to implement the interface method on a specific class, you can recast the object to the appropriate class to process class-specific members. You may think that the behavior of casting when applied to reference types may seem awkward or counter-intuitive, but once you understand them they make perfect sense and their utility starts to become apparent.

Steve Sawyer is a partner with Geeks and Gurus, Inc., a software development and IT services company in Detroit, MI. Steve has been working as a professional programmer since 1988. Co-author of two books on Visual FoxPro programming, including (with Jim Booth) "Effective Techniques for Application Development with Visual FoxPro," Steve is a former columnist and has written numerous articles on programming over the past ten years. Steve has been a Microsoft developer MVP from 1997-2002, a Microsoft Certified Professional since 1995, and is a founding member and President of the Detroit Area Fox User Group. You can reach him at sasawyer@geeksandgurus.com.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date