2009-10-12 6 views
1

J'essaye de créer un arbre d'expression contenant un appel de fonction à une fonction F # sur un certain module. Cependant, il me manque quelque chose parce que la fonction d'assistance System.Linq.Expressions.Expression.Call() ne peut pas trouver la fonction que je fournis.Appel d'une fonction F # via un noeud d'expression de méthode Linq MethodCallExpression?

L'appel() donne un appel InvalidOperationException: "Aucune méthode 'maFonction' du type '' TestReflection.Functions est compatible avec les arguments fournis."

Si quelqu'un peut me donner un indice sur Ce que je fais mal, ce serait très utile.

Voir le code ci-dessous:

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

Cordialement, Rickard

Répondre

3

Le troisième argument de Expression.Call est un tableau de paramètres de type générique - votre méthode n'est pas générique, ce qui devrait être null. Vous aurez également besoin de passer votre "un" argument à 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() 
+0

Cela fonctionne comme un charme - merci! – Rickard