2012-06-17 4 views
1

Можно ли передать функцию F # посредством Reflection?Можно ли передать функцию F # посредством 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 

Я не могу вызывать элемент без параметра 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

К сожалению, спасибо, что указали это. Исправлено в «bar». Второй пример кода вызывает элемент «bar» типа Foo, который я не хочу делать. Я подозреваю, что передача функции, как частичная функция, невозможна с отражением. –

+0

Что такое _problem_? Вы получаете ошибку компилятора или ошибку времени выполнения? – ildjarn

ответ

2

Проблема заключается в том, что GetMethod возвращается a 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

@Jack -see edit - вы просто завершаете вызов функцией –

Смежные вопросы