Domanda

Ho un oggetto di tipo FSharpOption, ma non so che sia profondità. Potrebbe essere uno qualsiasi di ...

FSharpOption<Int32>
FSharpOption<FSharpOption<Int32>>
FSharpOption<FSharpOption<FSharpOption<Int32>>>
FSharpOption<FSharpOption<FSharpOption<FSharpOption<Int32>>>>
etc.

Modifica: nota inoltre che non è necessariamente un Int32. Potrebbe essere qualsiasi tipo di base.

Come posso ottenere il valore di base utilizzando VB o C #?

È stato utile?

Soluzione

Potrebbe non essere indipendente dalla versione ... che ne dici di questa piccola variazione senza dipendenza da FSharp.Core?

static object OptionGetUnderlyingValue(object obj)
{
    while (obj != null && obj.GetType().Name == "FSharpOption`1")
    {
        PropertyInfo pi = obj.GetType().GetProperty("Value");
        Contract.Assert(pi != null);
        obj = pi.GetValue(obj, null);
    }

    return obj;
}

Altri suggerimenti

Non posso fare a meno di chiedermi come sei arrivato a questo stato in primo luogo.

Detto questo, supponendo che il tipo statico sia 'oggetto', quindi suppongo che dovrete vedere se il suo .GetType () è la definizione di tipo generico di FSharpOption`1, e usa la riflessione (o 'dinamico') per scartare un livello e riprovare ...

Non sono chiaro come questa sia una domanda F #, poiché si desidera la risposta in C # o VB, e la stessa domanda potrebbe essere posta a qualsiasi Foo < T > tipo.

Detto questo, ecco un po 'di codice C # 4.0:

    object o = FS.Foo.F(3);
    while (o.GetType().IsGenericType && 
           o.GetType().GetGenericTypeDefinition() == 
              typeof(Microsoft.FSharp.Core.FSharpOption<>))
    {
        dynamic d = o;
        o = d.Value;
    }
    Console.WriteLine(o);

e alcuni codici F #:

namespace FS

type Foo() = 
    static member F x =
        match x with
        | 1 -> Some 42 |> box
        | 2 -> Some(Some "forty-two") |> box
        | 3 -> Some(Some(Some 42)) |> box
        | _ -> failwith "no"

EDIT nota che l'ho modificato per mostrare che la strategia funziona anche se contiene cose diverse dai soli ints.

Ok, quindi questo è quello che ho finora. Qualche suggerimento su come migliorarlo?

Option Strict Off
Imports Microsoft.FSharp.Core

Public Module FSharpInterop
    Public Function OptionGetUnderlyingValue(ByVal value As Object) As Object
        If value Is Nothing Then Return Nothing
        Dim temp = value
        Do While temp.GetType.Name = "FSharpOption`1"
            temp = OptionModule.GetValue(temp)
            If temp Is Nothing Then Return Nothing
        Loop
        Return temp
    End Function
End Module
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top