Вызов функции F # через дерево выражений Linq в узле MethodCallExpression? - PullRequest
1 голос
/ 12 октября 2009

Я пытаюсь создать дерево выражений, содержащее вызов функции функции F # в определенном модуле. Однако я что-то упускаю, потому что вспомогательная функция System.Linq.Expressions.Expression.Call () не может найти функцию, которую я предоставляю.

Вызов Call () дает InvalidOperationException : " Нет метода" myFunction "для типа" TestReflection.Functions ", совместимого с предоставленными аргументами. "

Если кто-нибудь подскажет, что я делаю неправильно, это было бы очень полезно.

См. Код ниже:

namespace TestReflection

open System.Linq.Expressions

module Functions =
    let myFunction (x: float) =
        x*x

    let assem = System.Reflection.Assembly.GetExecutingAssembly()
    let modul = assem.GetType("TestReflection.Functions")
    let mi = modul.GetMethod("myFunction")
    let pi = mi.GetParameters()

    let argTypes =
        Array.map 
            (fun (x: System.Reflection.ParameterInfo) -> x.ParameterType) pi

    let parArray = 
        [| (Expression.Parameter(typeof<float>, "a") :> Expression); |]
    let ce = Expression.Call(modul, mi.Name, argTypes, parArray)

    let del = (Expression.Lambda<System.Func<float, float>>(ce)).Compile()

printf "%A" (Functions.del.Invoke(3.5))

С уважением, Рикард

1 Ответ

3 голосов
/ 12 октября 2009

Третий аргумент Expression.Call - это массив параметров универсального типа - ваш метод не является универсальным, поэтому он должен быть null. Вам также нужно будет передать аргумент "a" в Expression.Lambda:

    let a = Expression.Parameter(typeof<float>, "a")
    let parArray = [| (a :> Expression); |]
    let ce = Expression.Call(modul, mi.Name, null, parArray)

    let del = (Expression.Lambda<System.Func<float, float>>(ce, a)).Compile()
...