views:

299

answers:

1

Hello,

I am trying to create an expression tree containing a function call to a F# function on a certain module. However, I am missing something because the System.Linq.Expressions.Expression.Call() helper function cant find the function I'm supplying.

The Call() call gives an InvalidOperationException: "No method 'myFunction' on type 'TestReflection.Functions' is compatible with the supplied arguments."

If anyone can give me a hint on what I am doing wrong it would be very helpful.

See the code below:

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

Regards, Rickard

+2  A: 

The third argument to Expression.Call is an array of generic type parameters - your method is not generic, so that should be null. You'll also need to pass your "a" argument to 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()
dahlbyk
That works like a charm - thank you!
Rickard