如何打开未知深度的FSharpOption?

时间:2009-10-22 07:57:22

标签: .net f#

我有一个FSharpOption类型的对象,但我不知道它的深度。它可能是......

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

编辑:另请注意,它不一定是Int32。它可以是任何基础类型。

如何使用VB或C#获得底值?

3 个答案:

答案 0 :(得分:2)

我不禁想知道你是如何进入这种状态的。

那就是说,假设静态类型是'对象',那么我想你必须看看它的.GetType()是否是FSharpOption`1的泛型类型定义,并使用反射(或'动态')来打开一个级别再试一次......

我不清楚这是一个F#问题,因为你想在C#或VB中得到答案,并且可以询问任何Foo&lt; T&gt;的问题。类型。

所有人都说,这里有一些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);

和一些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"

编辑注意我更改了它以显示策略是否有效,即使它包含除了整数之外的其他内容。

答案 1 :(得分:1)

好的,这就是我到目前为止所做的。有关改进的建议吗?

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

答案 2 :(得分:1)

这可能与版本无关......这个微小变化如何不依赖于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;
}