通过Linq表达式TreeCallExpression节点调用F#函数?

时间:2009-10-12 17:37:40

标签: reflection f# expression-trees

我正在尝试创建一个表达式树,其中包含对某个模块上的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 个答案:

答案 0 :(得分:3)

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