BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 1.1+

C# Conversion Operator Overloading

The twelfth part of the C# Object-Oriented Programming tutorial completes the investigation of operator overloading in C#. This article describes the process for overloading conversion operators to allow implicit and explicit casting between data types.

The Conversion Operators

In the article, C# Numeric Type Conversion, I explained the use of casting. Casting permits a value of one type to be converted to another data type so that it can be used in a calculation or method or in any other situation where the value's current data type is unsuitable.

The conversion of data types provided by casting can be either implicit or explicit. An implicit cast occurs automatically when an implicit conversion operator has been defined and the two data types are compatible. An explicit cast is used when the two data types are not entirely compatible and requires the source type to be prefixed with a cast operator. This operator is the desired data type enclosed in parentheses ().

The following code sample shows a comparison of conversion using implicit and explicit casts for basic numeric data types. Note the requirement for the cast operator for the second conversion.

uint integer = 100;
long longInteger;

// Implicit cast
longInteger = integer;

// Explicit cast
integer = (uint)longInteger;

When you create a new class, it does not possess the capabilities to be cast to other data types. Each possible cast must be defined within the class and declared as either implicit or explicit. As can be seen in the above example code, the implicit cast can be easier to read and can provide neater code. However, it is not immediately apparent to the reader that a conversion is occurring and so implicit casting can hide problems that would be more apparent if an explicit cast operator were used.

As a rule of thumb, implicit casting should only be used where there is no risk of data loss or an exception being thrown. Explicit casting should be used in all other situations. This is demonstrated in the above code. Implicit casting from the smaller integer to the larger integer is risk-free as all possible values can be converted. For conversion from the large, signed integer to the smaller, unsigned integer there is a risk that the value will lose its sign or be too large to be converted so explicit casting is more appropriate.

There are some restrictions to overloading the conversion operators. The key restrictions are:

  • You may not create operators that convert a class to the object data type. Conversion to object is provided automatically to permit boxing and unboxing.
  • You may not create operators that convert a class to a defined interface. If conversion to an interface is required, the class must implement the interface. Interfaces will be described later in the C# Object-Oriented Programming tutorial.
  • You may not create operators that convert from a base class into a class derived from that base class. Class inheritance will be described later in this tutorial.

This article uses the Vector class developed over previous articles. The Vector class represents a two-dimensional vector and already overloads arithmetic operators, true and false operators, logical operators and relational operators. If you do not have the code, download it using the link above. You can then edit the program to add the new operators.

Creating an Implicit Conversion Operator

Syntax

The implicit and explicit cast operators are unary operators and, as such, are overridden using a similar syntax as other basic unary operators. The following syntax is for the implicit conversion operator:

public static implicit operator result-type(op-type operand)

The result-type is the data type for the return value of the operation, ie. the target type for the cast. The op-type is the data type for the operand that is to be converted. One of the two data types must be the same as the class in which the declaration is made.

Adding Double Conversion to the Vector Class

Using the syntax described above, we will now add an implicit conversion operator to the Vector class. This operator will cast a Vector to a double-precision floating point number representing the length of the Vector. The length calculation is already present as a property of the class so we will reuse this functionality. To add the new conversion operator, add the following code to the Vector class:

public static implicit operator double(Vector v)
{
    return v.Length;
}

You can test the new conversion operator by modifying the Main method of the program:

static void Main(string[] args)
{
    Vector v = new Vector(5, 5);

    double d = v;
    Console.WriteLine(d);           // Outputs 7.07106781186548
}
30 December 2007