F# Discriminated Union usage from C#
c#, c#-to-f#, f#
Solution
If you are writing a library in F# that is exposed to C# developers, then C# developers should be able to use it without knowing anything about F# (and without knowing that it was written in F#). This is also recommended by F# design guidelines.
For discriminated unions, this is tricky, because they follow different design principles than C#. So, I would probably hide all processing functionality (like calculating area) in the F# code and expose it as ordinary members.
If you really need to expose the two cases to C# developers, then I think something like this is a decent option for a simple discriminated union:
type Shape =
| Rectangle of float * float
| Circle of float
member x.TryRectangle(width:float byref, height:float byref) =
match x with
| Rectangle(w, h) -> width <- w; height <- h; true
| _ -> false
member x.TryCircle(radius:float byref) =
match x with
| Circle(r) -> radius <- r; true
| _ -> false
In C#, you can use it in the same way as the familiar `TryParse` methods:
int w, h, r;
if (shape.TryRectangle(out w, out h)) {
// Code for rectangle
} else if (shape.TryCircle(out r)) {
// Code for circle
}
Problem
What are the best ways to use F# Discriminated Unions from C#? I have been digging into this problem for a while, I have probably found the simplest way, but as it is rather complex, there may be some other thing I don't see... Having a discriminated union, e.g.: ``` type Shape = | Rectangle of float * float | Circle of float ``` the usage from C# I found would be (avoiding using vars, to make the type obvious): ``` Shape circle = Shape.NewCircle(5.0); if (circle.IsCircle) { Shape.Circle c = (Shape.Circle)circle; double radius = c.Item; } ``` In C#, the `NewXXXX` static methods always create object of the `Shape` class, there is also a method `IsXXXX` to check if the object is of the type; if and only if yes, it is castable to the `Shape.XXXX` class, and only then its items are accessible; constructor of the `Shape.XXXX` classes are internal, i.e. unaccessible. Is anyone aware of a simpler option to get the data from a discriminated union?