Data Structures and Algorithms with Object-Oriented Design Patterns in C#
next up previous contents index

Wrappers for Value Types

 

The value types  in C# are bool, char, schar, short, ushort, int, uint, long, ulong, float, and double. There is also the ``type'' void which is used in the place of the return type to declare a method that returns nothing. Whenever a value type is used in a context where an object is required, C# automatically boxes  the value type. Therefore, in C# a value parameter can be used wherever an object is expected.

Each C# value type is an alias for a struct in the System class. E.g., int is an alias for the struct System.Int32 and void is an alias for the struct System.Void. Since all C# structs are ultimately derived from the object class, they all implement the methods defined in that class. Specifically, a value types provide an Equals methods.

Furthermore, most (but not all) of the C# value types implement the IComparable interface. I.e., they provide a CompareTo method for comparing instances of the same type. Unfortunately, since the value types are not derived from the ComparableObject class it is not possible to use the operators shown in Program gif with value type instances.

To circumvent this shortcoming, we might be tempted to try something like this:

class ComparableInt32 :
    ComparableObject,
    System.Int32 // Wrong.  Int32 is a struct!
{
     // ...
}
Unfortunately, according to the C# language specification, Int32 is a struct--it cannot be extended[22]. Consequently, we are forced to implement our own wrapper classes if we want them to extend ComparableObject base class.

Program gif defines the ComparableValue abstract class that extends the ComparableObject base class. This class ``wraps'' an object that implements the IComparable interface.

   program4445
Program: More here

The ComparableValue class as a single field obj that refers to the wrapped IComparable object instance. The constructor takes a IComparable object reference and assigns it to the obj field. The Object property of the ComparableValue class provides a get accessor that returns the contained object instance. The GetHashCode and ToString methods simply delegate to the contained IComparable instance.

The CompareTo method compares a ComparableValue with a given object. The assumption is that the given object is also a ComparableValue. The CompareTo method compares the objects contained in the ComparableValue wrappers.

Programs gif, gif and gif define three wrapper classes ComparableChar, ComparableInt32, and ComparableDouble, which are wrappers for C# value types char, int, and double.

   program4477
Program: ComparableChar class.

   program4488
Program: ComparableInt32 class.

   program4499
Program: ComparableDouble class.

C# also provides the string class for dealing with character sequences. The string class is special in that it is closely tied to the definition of the language itself. The C# compiler automatically creates a string object for every string literal , such as "Hello world.\n", in a C# program. Program gif defines the class ComparableString which wraps a string instance using the ComparableValue class.

   program4519
Program: ComparableString class.

Using these classes it is now possible to write a sequence of statements like:

ComparableInt32 i = 1;
ComparableInt32 j = 2;
if (i > j)
    Console.WriteLine((int)i - (int)j);
In this sequence, the values 1 and 2 are first boxed by C#\ and then wrapped in instances of the ComparableInt32 class. The comparison operator invoked is that given in Program gif and the CompareTo method invoked is that given in Program gif.

Finally, to make it possible to deal with ComparableObjects only, a collection of conversion operators is defined in Program gif I.e., for each value type a implicit conversion is provided that wraps that value type in the corresponding ComparableValue class. Similarly, explicit conversion operators are provided to unwrap the contained values types.

   program4539
Program: More here

By using the methods given in Program gif, we can rewrite the code fragment given above as

ComparableObject i = 1;
ComparableObject j = 2;
if (i > j)
    Console.WriteLine((int)i - (int)j);
The effect of this code fragment is exactly as before. However, this time the objects are refered to by variables whose type is the abstract base class ComparableObject.


next up previous contents index

Bruno Copyright © 2001 by Bruno R. Preiss, P.Eng. All rights reserved.