## Wednesday, October 13, 2010

### Using C#'s implicit type conversions from other .NET languages

One interesting C# feature is the ability to define a method that implements implicit conversion from one type to another. In this post I'm going to show how to use this feature from IronPython, F#, VB.NET and IronRuby.

#### Example

In order to illustrate the implicit conversion feature we're going to use the following classes:

``namespace Langexplr.Experiments{   public class Complex    {       public double Real { get; set; }       public double Img { get; set; }              public static implicit operator Complex(double real)        {           return new Complex() { Real = real };       }       public static implicit operator Polar(Complex complex)        {           return new Polar() { Angle = Math.Atan(complex.Img/complex.Real),                                Length = Math.Sqrt(complex.Real*complex.Real +                                                   complex.Img*complex.Img) };       }           public static implicit operator double(Complex complex)        {           return Math.Sqrt(complex.Real*complex.Real +                            complex.Img*complex.Img);       }          }   public class Polar    {       public double Angle { get; set; }       public double Length { get; set; }   }}``

The `Complex` class is a simple definition of a complex number. The `Polar` class is defined(conveniently) to represent a complex number in polar form. The `Complex` class defines three implicit conversions:

1. From `double` to a complex number

2. From `Complex` to `Polar`

3. From `Complex` to `double`

The following C# code shows a use of this feature:

``using Langexplr.Experiments;using System;class main {   public static void Main(string[] args)   {           Complex c = 10.3;       Polar p = new Complex() {Real = 12.3, Img = 5.2};       double abs = c;       Console.WriteLine("abs:{0} Polar: {1},{2}", abs ,p.Angle ,p.Length);    } }``

By looking at the definitions generated by the compiler for the `Complex` class, we can see several definitions for the `op_Implicit` method with different parameters and return types.

``....method public hidebysig specialname static         class Langexplr.Experiments.Complex         op_Implicit(float64 real) cil managed....method public hidebysig specialname static         class Langexplr.Experiments.Polar         op_Implicit(class Langexplr.Experiments.Complex complex) cil managed....method public hidebysig specialname static         float64  op_Implicit(class Langexplr.Experiments.Complex complex) cil managed...``

Now these uses of the `Complex` class will be presented on different .NET languages.

#### IronPython

As described in "Dark Corners of IronPython" by Michael Foord the `clr.Convert` function can be used to convert between types using the `op_Implicit` if necessary.

For example:

``import clrclr.AddReference("ImplicitTest")from Langexplr.Experiments import *from System import Doublec = clr.Convert(10.3, Complex)nC = Complex()nC.Real = 12.3nC.Img = 5.2p = clr.Convert(nC, Polar)abs = clr.Convert(c, Double)print 'abs: %(0)f Polar: %(1)f,%(2)f\n' % \       { '0': abs, '1' : p.Angle, '2' : p.Length }``

#### IronRuby

IronRuby will use the `op_Implicit` definition if a conversion required at a particular call. I couldn't find a nice way to do this directly as with IronPython's `clr.Convert` . However the following function definition seems to do the trick:

``def dotnet_convert(value,type)   f =  System::Func[type,type].new {|x| x}   f.invoke(value)end``

This conversion function works since IronRuby tries to convert the value to the expected .NET type in the call to 'invoke' .

Using this definition we can write:

``require 'ImplicitTest.dll'c = dotnet_convert(10.3,Langexplr::Experiments::Complex)nC = Langexplr::Experiments::Complex.newnC.Real = 12.3nC.Img = 5.2p = dotnet_convert(nC,Langexplr::Experiments::Polar)abs = dotnet_convert(c,System::Double)print "abs: #{abs} Polar: #{p.Angle},#{p.Length} \n"``

#### F#

In F# we can call the `op_Implicit` method directly and F# will use type inference to determine the correct overload to use.

For example:
``open Langexplr.Experimentslet c : Complex = Complex.op_Implicit 10.3let p : Polar = Complex.op_Implicit (new Complex(Real=12.3, Img=5.2))let abs : double = Complex.op_Implicit cSystem.Console.WriteLine("1. {0} Polar: {1},{2} ", abs, p.Angle, p.Length )``

There's a nice post called "F# – Duck Typing and Structural Typing" by Matthew Podwysocki, which describes a nice way to define a generic function to use the op_Implicit operator.

``let inline convert (x:^a) : ^b =  ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x )``

This function can be used as follows:

``let c2:Complex = convert 10.3let p2:Polar = convert (new Complex(Real=12.3, Img=5.2))let abs2:float = convert cSystem.Console.WriteLine("2. {0} Polar: {1},{2} ",abs2,p2.Angle,p2.Length)``

#### VB.NET

Finally in Visual Basic .NET the implicit conversion is used automatically as in C#. For example:

``Imports SystemImports Langexplr.ExperimentsModule Test   Sub Main      Dim c As Complex = 10.3      Dim p As Polar = new Complex() With { _            .Real = 12.3, _            .Img = 5.2 _      }      Dim abs As Double = c      Console.WriteLine("abs:{0} Polar: {1},{2}",abs,p.Angle,p.Length)   End SubEnd Module``