Operator Overloading and Conversions

Operator overloading is the ability to redefine many of the built-in operators so that they have behavior specific to a custom type. For example, it would be convenient to overload addition and related mathematical operators for a custom matrix class. Similar in declaration to operator overloads, a type can declare its own conversions, where one type can be cast to another. Extending the example of a matrix class, it would be convenient to be able to convert a two-dimensional array into a custom matrix type. The following sections describe how to perform operator overloads and conversions.

Operator Overloading

An operator overload allows a type to use one of the standard C# operators on itself. A typical use of an operator overload is for types that act like the built-in numeric types, such as int or float. Just a word of caution here; operators should only be overloaded for situations where their use is natural, such as scientific or mathematical operations. Anything else could make code difficult to maintain and understand. Implementations that would make sense would be mathematical operations to support matrices or Cartesian coordinates. Listing 4.1 demonstrates how to overload the addition operator for a Point struct.

Listing 4.1 Addition Operator Overload (AdditionOverload.cs)
 using System; public struct Point {    public int X;    public int Y;    public Point(int x, int y)    {       X = x;       Y = y;    }    public static Point operator +(Point pt1, Point pt2)    {       Point ptOut = new Point();       ptOut.X = pt1.X + pt2.X;       ptOut.Y = pt1.Y + pt2.Y;       return ptOut;    } } class AdditionOverload {    static void Main()    {       Point pt1 = new Point(2, 3);       Point pt2 = new Point(2, 3);       Point pt3 = pt1 + pt2;       Console.WriteLine("pt3.X: {0} pt3.Y: {1}", pt3.X, pt3.Y);       Console.ReadLine();    } } 

As demonstrated in Listing 4.1, overloaded operators are declared by the following pattern:

 public static ReturnType operator OperatorType(Parameters) { } 

Several more things are important to remember about operator overloading. For consistent type implementation, some operators must be implemented together: == and !=, < and >, and <= and >=. It makes sense to implement these operators together because it preserves the semantic consistency of the type.

Another bit to remember about operators is that an overload also overloads its corresponding compound operator, for example, overloading + also overloads +=. This means that an operation such as pt2 += pt1 would make pt2 equal pt2 + pt1.

Conversions

Conversions make it possible to copy one type to another. They are implemented similar to operator overloads, except that there are two types of conversions: explicit and implicit. An explicit conversion forces the user to cast the value during assignment because there is potential of data loss or error. An implicit conversion happens automatically and should only be used when the conversion is absolutely safe. Be very careful with implicit conversions because sometimes types are converted unexpectedly, causing difficult-to-detect bugs. A conversion must be defined in one of the types participating in the conversion. Listing 4.2 shows how to declare and use both explicit and implicit conversions.

Listing 4.2 Explicit and Implicit Conversions (Conversions.cs)
 using System; public struct Point {    public int X;    public int Y;    public Point(int x, int y)    {       X = x;       Y = y;    }    public static explicit operator Point(Offset of)    {       return new Point(of.X, of.Y);    } } public struct Offset {    public int X;    public int Y;    public Offset(int x, int y)    {       X = x;       Y = y;    }    public static implicit operator Offset(Point pt)    {       return new Offset(pt.X, pt.Y);    } } class Conversions {    static void Main()    {       Point  pt1 = new Point(2, 3);       Offset of1 = new Offset(4, 6);       Offset of2 = pt1;       Console.WriteLine("of2.X: {0} of2.Y: {1}", of2.X, of2.Y);       Point pt2 = (Point)of1;       Console.WriteLine("pt2.X: {0} pt2.Y: {1}", pt2.X, pt2.Y);       Console.ReadLine();    } } 

As shown in Listing 4.2, implicit operators allow one type to be assigned to the other seamlessly. However, explicit conversions require a cast operator, as in the case of Point pt2 = (Point)of1.



C# Builder KickStart
C# Builder KickStart
ISBN: 672325896
EAN: N/A
Year: 2003
Pages: 165

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