Using F # discriminatory joins from C # is a little inelegant because of how they are compiled.
I think the best approach is to define some members (on the F # side) that will make it easier to use types from C #. There are several options, but I prefer to define the TryLeft and TryRight , which behave similarly to Int32.TryParse (and therefore they should be familiar to C # developers using your F # API):
open System.Runtime.InteropServices type Either<'a,'b> = | Left of 'a | Right of 'b member x.TryLeft([<Out>] a:byref<'a>) = match x with Left v -> a <- v; true | _ -> false member x.TryRight([<Out>] b:byref<'b>) = match x with Right v -> b <- v; true | _ -> false
Then you can use the type from C # as follows:
int a; string s; if (v.TryLeft(out a)) Console.WriteLine("Number: {0}", a); else if (v.TryRight(out s)) Console.WriteLine("String: {0}", s);
You lose some of the security of F # by doing this, but it was expected in a language without pattern matching. But itβs good that anyone familiar with .NET should be able to use the API implemented in F #.
Another alternative would be to define a Match member that accepts the delegates Func<'a> and Func<'b> and calls the right delegate with the value carried in the case of left / right. This is slightly better from a functional point of view, but it may be less obvious to C # callers.
source share