Conversion Operators


In some situations, you will want to use an object of a class in an expression involving other types of data. Sometimes, overloading one or more operators can provide the means of doing this. However, in other cases, what you want is a simple type conversion from the class type to the target type. To handle these cases, C# allows you to create a special type of operator method called a conversion operator. A conversion operator converts an object of your class into another type. In essence, a conversion operator overloads the cast operator. Conversion operators help fully integrate class types into the C# programming environment by allowing objects of a class to be freely mixed with other data types as long as a conversion to those other types is defined.

There are two forms of conversion operators, implicit and explicit. The general form for each is shown here:

 public static operator implicit target-type(source-type v) { return value; } public static operator explicit target-type(source-type v) { return value; }

Here, target-type is the target type that you are converting to, source-type is the type you are converting from, and value is the value of the class after conversion. The conversion operators return data of type target-type, and no other return type specifier is allowed.

If the conversion operator specifies implicit, then the conversion is invoked automatically, such as when an object is used in an expression with the target type. When the conversion operator specifies explicit, the conversion is invoked when a cast is used. You cannot define both an implicit and explicit conversion operator for the same target and source types.

To illustrate a conversion operator, we will create one for the ThreeD class. Suppose you want to convert an object of type ThreeD into an integer so it can be used in an integer expression. Further, the conversion will take place by using the product of the three dimensions. To accomplish this, you will use an implicit conversion operator that looks like this:

 public static implicit operator int(ThreeD op1) {   return op1.x * op1.y * op1.z; }

Here is a program that illustrates this conversion operator:

 // An example that uses an implicit conversion operator. using System; // A three-dimensional coordinate class. class ThreeD {   int x, y, z; // 3-D coordinates   public ThreeD() { x = y = z = 0; }   public ThreeD(int i, int j, int k) { x = i; y = j; z = k; }   // Overload binary +.   public static ThreeD operator +(ThreeD op1, ThreeD op2)   {     ThreeD result = new ThreeD();     result.x = op1.x + op2.x;     result.y = op1.y + op2.y;     result.z = op1.z + op2.z;     return result;   }   // An implicit conversion from ThreeD to int.   public static implicit operator int(ThreeD op1)   {     return op1.x * op1.y * op1.z;   }   // Show X, Y, Z coordinates.   public void show()   {     Console.WriteLine(x + ", " + y + ", " + z);   } } class ThreeDDemo {   public static void Main() {     ThreeD a = new ThreeD(1, 2, 3);     ThreeD b = new ThreeD(10, 10, 10);     ThreeD c = new ThreeD();     int i;     Console.Write("Here is a: ");     a.show();     Console.WriteLine();     Console.Write("Here is b: ");     b.show();     Console.WriteLine();     c = a + b; // add a and b together     Console.Write("Result of a + b: ");     c.show();     Console.WriteLine();     i = a; // convert to int     Console.WriteLine("Result of i = a: " + i);     Console.WriteLine();     i = a * 2 - b; // convert to int     Console.WriteLine("result of a * 2 - b: " + i);   } }

This program displays the output:

 Here is a: 1, 2, 3 Here is b: 10, 10, 10 Result of a + b: 11, 12, 13 Result of i = a: 6 result of a * 2 - b: -988

As the program illustrates, when a ThreeD object is used in an integer expression, such as i = a, the conversion is applied to the object. In this specific case, the conversion returns the value 6, which is the product of coordinates stored in a. However, when an expression does not require a conversion to int, the conversion operator is not called. This is why c = a+b does not invoke operator int( ).

Remember that you can create different conversion functions to meet different needs. You could define one that converts to double or long, for example. Each is applied automatically and independently.

An implicit conversion operator is applied automatically when a conversion is required in an expression, when passing an object to a method, in an assignment, and also when an explicit cast to the target type is used. Alternatively, you can create an explicit conversion operator, which is invoked only when an explicit cast is used. An explicit conversion operator is not invoked automatically. For example, here is the previous program reworked to use an explicit conversion to int:

 // Use an explicit conversion. using System; // A three-dimensional coordinate class. class ThreeD {   int x, y, z; // 3-D coordinates   public ThreeD() { x = y = z = 0; }   public ThreeD(int i, int j, int k) { x = i; y = j; z = k; }   // Overload binary +.   public static ThreeD operator +(ThreeD op1, ThreeD op2)   {     ThreeD result = new ThreeD();     result.x = op1.x + op2.x;     result.y = op1.y + op2.y;     result.z = op1.z + op2.z;     return result;   }   // This is now explicit.   public static explicit operator int(ThreeD op1)   {     return op1.x * op1.y * op1.z;   }   // Show X, Y, Z coordinates.   public void show()   {     Console.WriteLine(x + ", " + y + ", " + z);   } } class ThreeDDemo {   public static void Main() {     ThreeD a = new ThreeD(1, 2, 3);     ThreeD b = new ThreeD(10, 10, 10);     ThreeD c = new ThreeD();     int i;     Console.Write("Here is a: ");     a.show();     Console.WriteLine();     Console.Write("Here is b: ");     b.show();     Console.WriteLine();     c = a + b; // add a and b together     Console.Write("Result of a + b: ");     c.show();     Console.WriteLine();     i = (int) a; // explicitly convert to int -- cast required     Console.WriteLine("Result of i = a: " + i);     Console.WriteLine();     i = (int)a * 2 - (int)b; // casts required     Console.WriteLine("result of a * 2 - b: " + i);   } }

Because the conversion operator is now marked as explicit, conversion to int must be explicitly cast. For example, in this line:

 i = (int) a; // explicitly convert to int -- cast required

if you remove the cast, the program will not compile.

There are a few restrictions to conversion operators:

  • Either the target type or the source type of the conversion must be the class in which the conversion is declared. You cannot, for example, redefi ne the conversion from double to int.

  • You cannot define a conversion to or from object.

  • You cannot define both an implicit and an explicit conversion for the same source and target types.

  • You cannot define a conversion from a base class to a derived class. (See Chapter 11 for a discussion of base and derived classes.)

  • You cannot defi ne a conversion from or to an interface. (See Chapter 12 for a discussion of interfaces.)

In addition to these rules, there are suggestions that you should normally follow when choosing between implicit and explicit conversion operators. Although convenient, implicit conversions should be used only in situations in which the conversion is inherently error-free. To ensure this, implicit conversions should be created only when these two conditions are met: First, that no loss of information, such as truncation, overflow, or loss of sign, occurs. Second, that the conversion does not cause an exception. If the conversion cannot meet these two requirements, then you should use an explicit conversion.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

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