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.