I am trying to use FSharpChoice
type in a C# project. I have created a choice like so
var a = FSharpChoice.NewChoice1Of3(instofT
I probably wouldn't use the type directly from C# - you can do that, but the resulting code won't be very nice. I'd probably declare my own Choice
type that would look like this:
type Choice<'T1, 'T2> private (opt1, opt2) =
member x.TryGetChoice1Of2(arg:byref<'T1>) = //'
match opt1 with
| Some v -> arg <- v; true
| _ -> false
// Similar code for 'TryGetChoice2Of2'
type Choice = // static methods for creating (Choice1Of2, ...)
This uses byref
parameters which appear as out
parameters in C#, so you could write:
int num;
string str;
if (choice.TryGetChoice1Of2(out num)) // ...
else if (choice.TryGetChoice2Of2(out str)) // ...
else // assert(false)
This is definitely more pleasant way of working with the type from C# (and it uses pattern familiar from, for example, working with Int32.TryParse
).
Cast the value to FSharpChoice<T1,T2,T3>.Choice1Of3
and use the Item
property.
See Compiled Form of Union Types for Use from Other CLI Languages in the F# spec for more information about how discriminated unions are represented.
I recently started a project to make a "compatibility layer" so that FSharp.Core can be more easily consumed from C#. In particular, it makes generic discriminated unions usable from C#, for example:
var choice = Choice.New1Of3<int,string,string>(100);
int r = choice.Match(i => i + 21, s => s.Length + 1, s => s.Length + 5);
This does pattern matching on the discriminated union, similarly to how you would do it in F#, except there are no names.