代码之家  ›  专栏  ›  技术社区  ›  Rickard

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

  •  1
  • Rickard  · 技术社区  · 16 年前

    我试图创建一个表达式树,其中包含对某个模块上的F#函数的函数调用。然而,我遗漏了一些东西,因为 助手函数找不到我提供的函数。

    Call()调用给出一个 无效操作例外 类型“TestReflection.Functions”上的方法“myFunction”与提供的参数不兼容。 "

    如果有人能给我一个关于我做错了什么的提示,那将是非常有帮助的。

    请参阅下面的代码:

    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 回复  |  直到 16 年前
        1
  •  3
  •   dahlbyk    16 年前

    第三个论点是 Expression.Call 是泛型类型参数的数组-您的方法不是泛型的,因此应该是 null 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()