开发者

How do I unwrap an FSharpOption of unknown depth?

I have an object of type FSharpOption, but I don't know it's depth. It could be any of...

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

Edit: Also no开发者_StackOverflow中文版te that it isn't necessarily an Int32. It could be any underlying type.

How do I get at the underling value using VB or C#?


I can't help but wonder how you got into this state in the first place.

That said, assuming the static type is 'object', then I guess you'll have to see if its .GetType() is the generic type definition of FSharpOption`1, and use reflection (or 'dynamic') to unwrap one level and try again...

I am unclear how this is an F# question, since you want the answer in C# or VB, and the same question could be asked of any Foo<T> type.

That all said, here's some C# 4.0 code:

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

and some F# code:

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 note that I changed it to show the strategy works even if it contains things other than just ints.


That may not be version independent... how about this minor variation with no dependency on 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;
}


Ok, so this is what I have so far. Any suggestions on improving it?

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜