Reputation: 945
Is it possible to pass a F# function by Reflection?
(*in module A*)
type Foo() =
static member bar n = {1..n}
let functionUsingFoobar (x:(int -> #('a seq)) n =
let z = BarFoo.ofSeq (x n)
z.count
(* in module B
here is where I want to pass Foo.bar by reflection*)
let y = functionUsingFoobar Foo.bar 1000
I cannot invoke the member without the args parameter, so partial function application through InvokeMember cannot work.
let foo = new Foo()
let z = foo.GetType().InvokeMember("bar", System.Reflection.BindingFlags.InvokeMethod, null, foo, [|1000|])
(*tried null, [||], [|null|] for args parameter*)
I'm out of ideas how to pass the function by reflection
Upvotes: 1
Views: 361
Reputation: 25526
If this is what I think you want, it works just fine
type Foo() =
static member bar n = {1..n}
let functionUsingFoobar (x:(int -> #('a seq))) n =
(x n) |> Seq.length
let y = functionUsingFoobar Foo.bar 1000
let foo = new Foo()
let z = fun t -> foo.GetType().InvokeMember("bar", System.Reflection.BindingFlags.InvokeMethod, null, foo, [|t|])
Upvotes: 0
Reputation: 55185
The problem is that GetMethod
returns a MethodInfo
, but you need an F# function value. The easiest way to overcome this mismatch is probably to use CreateDelegate
to create a .NET delegate from the method, and then treat the Invoke
method as a function value of the correct type:
let d =
typeof<Foo>.GetMethod("bar").CreateDelegate(typeof<System.Func<int,seq<int>>>)
:?> System.Func<int,seq<int>>
functionUsingFooBar d.Invoke 1000
Upvotes: 2