Custom type conversion
Friday, February 27th, 2009 by Alejandro MehringIt’s always useful to redefine operators on your custom types, for they make it easier to follow and mantain the code you’re writting.
So why not do the same with casting operators?
Intro
Sometimes you create a new type and need to redefine certain operators in order to make your life easier. For instance, matrix or complex numbers operations. It’s way more comfortable (and understandable) to write a simple plus symbol than calling a method to perform an addition.
It’s pretty straightforward: you define a static method with the keyword operator such as this:
//Complex addition
public static Complex operator +(Complex a, Complex b)
{
a.Re = a.Re + b.Re;
a.Im = a.Im + b.Im;
return a;
}
And then you just forget about that and simply use it! So… why not also forget about type conversion?
Your custom type conversion
In certain cases you need to create a constructor that receives an object and “converts” it to another, or a method to change it backwards.
Supose you have Rectangular and Polar types. You could have the following code to perform the conversion between each of them:
//Rectangular type
public Rectangular(Polar polar)
{
X = polar.R * Math.Cos(polar.Theta);
Y = polar.R * Math.Sin(polar.Theta);
}
public Polar ToPolar()
{
Polar polar = new Polar();
polar.R = Math.Sqrt(X * X + Y * Y);
polar.Theta = Math.Atan2(X, Y);
return polar;
}
//Polar Type
public Polar(Rectangular rectangular)
{
R = Math.Sqrt(rectangular.X * rectangular.X + rectangular.Y * rectangular.Y);
Theta = Math.Atan2(rectangular.X, rectangular.Y);
}
public Rectangular ToRectangular()
{
Rectangular rectangular = new Rectangular();
rectangular.X = R * Math.Cos(Theta);
rectangular.Y = R * Math.Sin(Theta);
return rectangular;
}
//Usage example
Rectangular r = new Rectangular(3,1);
Polar p = new Polar(r);
Polar p2 = r.ToPolar();
Rectangular r2 = new Rectangular(p);
Instead of that, you could define your own type conversion as follows:
//Polar type
public static explicit operator Polar (Rectangular r) {
Polar p;
p.R = Math.Sqrt(r.X * r.X + r.Y * r.Y);
p.Theta = Math.Atan2(r.X, r.Y);
return p;
}
//Rectangular type
public static explicit operator Rectangular (Polar p) {
Rectangular r= new Rectangular();
r.X = p.R * Math.Cos(p.Theta);
r.Y = p.R * Math.Sin(p.Theta);
return r;
}
And then use it like usual
Rectangular r = new Rectangular(3,2); Polar p = (Polar)r;
A word on method declaration
The method declared must be static for conversion to work without creating an instance of target type first. It should also be visible in other scopes, so it should be public or at least internal.
The explicit operator expression shows that the conversion must be explicit. You could also define it as implicit, in which case the assignment in our example would only be Polar p = r; I personally dislike this option since it can lead to unwanted results.
The name of the method must be the name of the target type of conversion.
The parameter is the instance to be converted.
References
Tags: C#, dotnet, type conversion
