Как развернуть FSharpOption неизвестной глубины? - PullRequest
1 голос
/ 22 октября 2009

У меня есть объект типа FSharpOption, но я не знаю его глубину. Это может быть любой из ...

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

Редактировать: Также обратите внимание, что это не обязательно Int32. Это может быть любой базовый тип.

Как мне получить нижестоящее значение с помощью VB или C #?

Ответы [ 3 ]

2 голосов
/ 22 октября 2009

Я не могу не задаться вопросом, как вы попали в это состояние в первую очередь.

Тем не менее, предполагая, что статическим типом является 'объект', тогда я предполагаю, что вам придется посмотреть, является ли его .GetType () определением универсального типа для FSharpOption`1, и использовать отражение (или «динамический») для разверните один уровень и попробуйте снова ...

Мне неясно, как это вопрос F #, поскольку вы хотите получить ответ в C # или VB, и тот же вопрос можно задать для любого типа Foo .

Это все сказано, вот код 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 голос
/ 28 октября 2009

Это может не зависеть от версии ... как насчет этого незначительного изменения без зависимости от 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;
}
1 голос
/ 22 октября 2009

Хорошо, это то, что я имею до сих пор. Есть предложения по улучшению?

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...