2012-06-17 134 views
1

是否可以通过Reflection来传递F#函数?是否有可能通过Reflection来传递F#函数?

(*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 

我无法调用没有args参数的成员,所以通过InvokeMember的部分函数应用程序无法工作。

let foo = new Foo() 
let z = foo.GetType().InvokeMember("bar", System.Reflection.BindingFlags.InvokeMethod, null, foo, [|1000|]) 
(*tried null, [||], [|null|] for args parameter*) 

我的想法如何通过反射

+0

我不明白你怎么第二个代码示例连接到第一个 - 什么是seqIntAsc? – kvb

+0

糟糕 - 谢谢你指出。更正为“酒吧”。第二个代码示例调用Foo类型的“bar”成员,这不是我想要做的。我怀疑像部分函数那样传递函数是不可能的。 –

+0

什么是实际_problem_?你有编译器错误还是运行时错误? – ildjarn

回答

2

的问题是,GetMethod回报一个MethodInfo,但你需要一个F#函数值。要克服这种不匹配的最简单的方法可能是使用CreateDelegate创建从方法的.NET委托,然后处理Invoke方法正确类型的函数值:

let d = 
    typeof<Foo>.GetMethod("bar").CreateDelegate(typeof<System.Func<int,seq<int>>>) 
    :?> System.Func<int,seq<int>> 
functionUsingFooBar d.Invoke 1000 
0

传递功能。如果这是我想你想,它工作得很好

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|]) 
+0

不,这个“调用”即执行Foo.bar。我想将函数Foo.bar传递给函数“functionUsingFoobar”,以便在functionUsingFoobar中执行。但是,我想通过反射来选择Foo.bar(这样我就可以使用反射来选择与Foo.bar具有相同签名的任何其他函数,并改为传递它)。 –

+0

@杰克 - 见编辑 - 你只是用一个函数包装呼叫 –

相关问题