2016-03-29 13 views
7

Jestem w projekcie współdzielonym C#, próbując znaleźć odpowiednik PCL (Profil 259) dla FSharpValue.GetUnionFields.Jak osiągnąć `FSharpValue.GetUnionFields` w C# PCL (Profil 259)

W przeglądarce obiektu poprzez projektu C#, widzę

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); 
    } 
} 

To wydaje się być to, czego szukam, ale jestem w stanie (lub nie wiem jak), aby wywołać ją od C# . Przez F #, jeśli otworzę przestrzeń nazw, mogę nazwać rozszerzenie FSharpValue.GetUnionFields. FSharpValue.GetUnionFields nie kompiluje się z C# PCL. Nie mam doświadczenia z F #, więc może być tak, że brakuje mi jakiejś ważnej wiedzy związanej z interakcją F # - C#?

Dla odniesienia, to jest to, co widzę z F # pcl.

[<AutoOpen>] 
module Microsoft.FSharp.Reflection.FSharpReflectionExtensions 
open Microsoft.FSharp.Reflection 

val GetUnionFields : value:obj * unionType:System.Type * ?allowAccessToPrivateRepresentation:bool -> UnionCaseInfo * obj [] 

projekt Repro tutaj: https://github.com/kennethito/StackOverflowReferences/tree/master/FSharpValue-GetUnionFields

+1

Kiedy mówisz „żaden z poniższej pracy”, co to znaczy? Co się stanie, gdy spróbujesz to zrobić? –

+0

Nie mogę uzyskać żadnych połączeń związanych z GetUnionCases do kompilacji z projektu C#. Wszystkie listy błędów związanych z [Typ] nie zawierają deklaracji dla [Metoda]. Zasadniczo po prostu nie wiem jak poprawnie wywołać rozszerzenie z C# –

+0

Można użyć 'FSharpValue.GetUnionFields', aby go nazwać ... – Ringil

Odpowiedz

2

Ponownie, wymaga to przy użyciu odbicia. Ponieważ jest to PCL, jest to szczególnie nieprzyjemne, ponieważ faktyczna wersja FSharp.Core załadowana w czasie wykonywania jest tą, która ma znaczenie.

Poniższa powinno działać:

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 }); 
} 

ten próbuje znaleźć sposób bezpośrednio od typu (jak jest określony w FSharp.Core 4.4) i spada z powrotem do struktury PCL (jako metodę rozszerzenia) .

Poniższy aplikacji konsoli C# pokazuje to działa:

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(); 
}