I'm in a C# shared project trying to find the PCL (Profile 259) equivalent for FSharpValue.GetUnionFields
.
In object browser via the C# project, I see
namespace Microsoft.FSharp.Reflection
{
[AutoOpen]
[CompilationMapping(SourceConstructFlags.Module)]
public static class FSharpReflectionExtensions
{
public static Tuple<UnionCaseInfo, object[]> FSharpValue.GetUnionFields.Static(object value, Type unionType, [OptionalArgument] FSharpOption<bool> allowAccessToPrivateRepresentation);
}
}
This appears to be what I'm looking for, but I'm unable (or don't know how) to call it from C#. Via F#, if I open the namespace, I can call the extension FSharpValue.GetUnionFields
. FSharpValue.GetUnionFields
does not compile from a c# PCL. I'm not experienced with F# so it could be I'm just lacking some important piece of knowledge related to F# - C# interop?
For reference, this is what I see from a F# pcl.
[<AutoOpen>]
module Microsoft.FSharp.Reflection.FSharpReflectionExtensions
open Microsoft.FSharp.Reflection
val GetUnionFields : value:obj * unionType:System.Type * ?allowAccessToPrivateRepresentation:bool -> UnionCaseInfo * obj []
Repro project here: https://github.com/kennethito/StackOverflowReferences/tree/master/FSharpValue-GetUnionFields
Again, this requires using reflection. Since it's a PCL, it's particularly nasty, as the actual version of FSharp.Core loaded at runtime is the one that will matter.
The following should work:
public static Tuple<UnionCaseInfo, object[]> TestIt()
{
var option = new FSharpOption<int>(123);
MethodInfo method;
try
{
// If "4.4.0.0" is loaded at runtime, get directly
var t = typeof(FSharpValue);
method = t.GetRuntimeMethods().First(mi => mi.Name == "GetUnionFields");
}
catch
{
var t = typeof(FSharpReflectionExtensions);
method = t.GetRuntimeMethods().First(mi => mi.Name == "FSharp.Value.GetUnionFields.Static");
}
return (Tuple<UnionCaseInfo, object[]>)method.Invoke(null, new object[] { option, option.GetType(), null });
}
This tries to find the method directly on the type (how it's specified in FSharp.Core 4.4), and falls back to the PCL structure (as an extension method).
The following C# console application shows it working:
static void Main(string[] args)
{
Tuple<UnionCaseInfo, object[]> results = CsharpPortable.Test.TestIt();
var uci = results.Item1;
Console.WriteLine("{0}:", uci.Name);
foreach (var pi in uci.GetFields())
{
Console.WriteLine("Property: {0}", pi.Name);
}
Console.ReadKey();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With