128 votes

convertir un .net Func<T> vers un .net Expression<><T></T></>></T>

Passant un lambda à une Expression est facile en utilisant un appel de méthode...

Mais je voudrais tourner le bouton Func dans une expression, que dans des cas rares...

La ligne qui ne fonctionne pas me donne l’erreur de compilation `` . Un cast explicite ne résout pas la situation. Y a-t-il une facilité à faire ce que j’ai oublie ?

109voto

Mehrdad Afshari Points 204872

Ooh, c'est pas du tout facile. Func<T> représente un générique delegate et non pas une expression. Si il n'y a aucune façon vous pouvez le faire (en raison d'optimisations et d'autres choses faites par le compilateur, certaines données peuvent être jetés, de sorte qu'il peut être impossible d'obtenir l'expression d'origine à l'arrière), ce serait de démonter le IL à la volée et en déduire l'expression (ce qui n'est pas facile). Le traitement des expressions lambda comme données (Expression<Func<T>>) est une magie faite par le compilateur (en gros, le compilateur crée une arborescence d'expression dans le code au lieu de le compiler à l'IL).

Liées fait

C'est pourquoi les langues qui poussent les lambdas à l'extrême (comme Lisp) sont souvent plus faciles à mettre en œuvre que des interprètes. Dans ces langues, le code et les données sont essentiellement la même chose (même au moment de l'exécution), mais notre puce ne peut pas comprendre que la forme de code, nous avons donc pour émuler une machine de ce type par la construction d'un interprète sur le dessus de ce qui la comprend (le choix fait par Lisp comme langues) ou sacrifier la puissance (le code ne sera plus exactement égale à données) dans une certaine mesure (le choix fait par C#). En C#, le compilateur donne l'illusion de traitement de code de données en permettant lambdas être interprété comme code (Func<T>) et de données (Expression<Func<T>>) au moment de la compilation.

39voto

Override Points 59
    private static Expression<Func<T, bool>> FuncToExpression<T>(Func<T, bool> f)  
    {  
        return x => f(x);  
    } 

22voto

Ch00k Points 5901

Ce qui sans doute faire, est la méthode faire demi-tour. Prendre dans une Expression >, de compiler et d’exécuter. Si elle échoue, vous avez déjà l’Expression d’approfondir.

Évidemment, vous avez besoin d’examiner l’incidence sur les performances de ce et déterminer si c’est quelque chose que vous devez vraiment faire.

7voto

Steve Willcock Points 11859

Vous pouvez aller de l’autre façon via le. Méthode compile() cependant - ne sais pas si cela est utile pour vous :

3voto

aaguiar Points 104

Evain JB de l’équipe de Cecil Mono fait quelques progrès pour ce faire

http://Evain.net/blog/articles/2009/04/22/converting-Delegates-to-expression-Trees

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X