Question

Voici le contexte de ma question:

Une technique courante consiste à déclarer le paramètre d'une méthode sous la forme d'une expression Lambda plutôt que d'un délégué. C’est pour que la méthode puisse examiner l’expression afin de faire des choses intéressantes, comme rechercher le nom des appels de méthode dans le corps de l’instance de délégué.

Le problème, c’est que vous perdez certaines des fonctionnalités d’intelli-sense de Resharper. Si le paramètre de la méthode a été déclaré en tant que délégué, Resharper vous aiderait lors de l'écriture de l'appel de cette méthode, vous invitant à entrer x = > Syntaxe x à fournir comme valeur d'argument à cette méthode.

Alors ... revenons à ma question, je voudrais faire ce qui suit:

    MethodThatTakesDelegate(s => s.Length);
}

private void MethodThatTakesDelegate(Func<string, object> func)
{
    //convert func into expression
    //Expression<Func<string, object>> expr = "code I need to write"

    MethodThatTakesExpression(expr);
}


private void MethodThatTakesExpression(Expression<Func<string, object>> expr)
{
    //code here to determine the name of the property called against string (ie the Length)
}
Était-ce utile?

La solution

Partout où vous utilisez le terme "expression lambda" vous voulez dire "arbre d'expression".

Une expression lambda est le bit du code source qui est

parameters => code

par exemple

x => x * 2

Les arbres d'expression sont des instances de System.Linq .Expressions.Expression (ou l’une des classes dérivées) représentant le code en tant que données.

Les expressions Lambda sont converties par le compilateur en instances d'arbre d'expression (ou plutôt en code générant une arborescence d'expression au moment de l'exécution) ou instances de délégué.

Vous pouvez compiler une instance de LambdaExpression (qui est l’une des sous-classes d’Expression) en délégué, mais vous ne pouvez pas faire l’inverse.

En théorie, il pourrait être possible d'écrire un tel "décompilateur". basé sur l'IL renvoyé par MethodBase.GetMethodBody dans certaines situations, mais il existe actuellement divers délégués qui ne peuvent pas être représentés par des arbres d'expression. Un arbre d'expression représente une expression plutôt qu'une instruction ou un bloc d'instructions - il n'y a donc pas de boucle, de branchement (sauf les conditions), d'affectation, etc. Je pense que cela peut changer dans .NET 4.0, bien que je ne m'attende pas à une étape de décompilation de la part de Microsoft à moins d’une très bonne raison.

Autres conseils

Je ne crois pas qu'il soit possible de réaliser ce que vous souhaitez ici. D'après les commentaires dans votre code, il semble que vous tentiez de capturer le nom de la propriété qui a effectué l'affectation dans MethodThatTakesExpression. Cela nécessite une expression lambda de l'arbre d'expression qui capture le contexte de l'accès à la propriété.

Au moment où vous passez un délégué à MethodThatTakesDelegate, ce contexte est perdu. Les délégués stockent uniquement une adresse de méthode, pas de contexte concernant les informations de méthode. Une fois cette conversion effectuée, il est impossible de la récupérer.

Un exemple de pourquoi cela n’est pas possible est qu’il n’existe même pas de méthode nommée sauvegardant un délégué. Il est possible d’utiliser ReflectionEmit pour générer une méthode qui n’a aucun nom et n’existe que dans la mémoire. Il est cependant possible d'affecter cela à un objet Func.

Non, ce n'est pas possible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top