Data Structures and Algorithms
with Object-Oriented Design Patterns in C# |
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 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 defines the ComparableValue abstract class that extends the ComparableObject base class. This class ``wraps'' an object that implements the IComparable interface.
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 , and define three wrapper classes ComparableChar, ComparableInt32, and ComparableDouble, which are wrappers for C# value types char, int, and double.
Program: ComparableChar class.
Program: ComparableInt32 class.
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 defines the class ComparableString which
wraps a string instance using the ComparableValue class.
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 and the CompareTo method invoked is that given in Program .
Finally, to make it possible to deal with ComparableObjects only, a collection of conversion operators is defined in Program 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.
By using the methods given in Program , 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.