Pourquoi utiliser Expression<Func<T>> plutôt que Func<T> ?

Pourquoi utiliser Expression<Func> plutôt que Func ?

Lorsque vous souhaitez traiter les expressions lambda comme des arbres d’expression et les examiner au lieu de les exécuter. Par exemple, LINQ to SQL obtient l’expression et la convertit en l’instruction SQL équivalente qu’il soumet au serveur (plutôt que d’exécuter la lambda).

Conceptuellement, Expression<Func<T>> est complètement différent de Func<T>. Func<T> désigne un delegate qui est essentiellement un pointeur vers une méthode, et Expression<Func<T>> désigne une structure de données arborescente pour une expression lambda. Cette structure arborescente décrit ce que fait une expression lambda plutôt que de faire la chose réelle. Elle contient essentiellement des données sur la composition des expressions, les variables, les appels de méthodes, etc. (par exemple, elle contient des informations telles que : cette lambda est une certaine constante + un certain paramètre). Vous pouvez utiliser cette description pour la convertir en une méthode réelle (avec Expression.Compile) ou faire d’autres choses (comme l’exemple LINQ to SQL) avec elle. Le fait de traiter les lambdas comme des méthodes anonymes et des arbres d’expression est purement une affaire de compilation.

Func<int> myFunc = () => 10; // similar to: int myAnonMethod() { return 10; }

sera effectivement compilé en une méthode IL qui ne prend rien et retourne 10.

Expression<Func<int>> myExpression = () => 10;

sera converti en une structure de données qui décrit une expression qui ne prend aucun paramètre et retourne la valeur 10 :

image agrandie

Bien que les deux se ressemblent au moment de la compilation, ce que le compilateur génère est totalement différent.