2012-06-17 86 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

@傑克 - 見編輯 - 你只是用一個函數包裝呼叫 –

相關問題