72 votes

Quel est l'objectif de la classe Expression ?

Je me demande quelle est exactement la différence entre envelopper un délégué à l'intérieur de Expression<> et non ?

Je vois Expression<Foo> est très utilisé avec LinQ, mais jusqu'à présent je n'ai pas trouvé d'article qui explique la différence entre ceci et l'utilisation d'un délégué.

Par exemple

Func<int, bool> Is42 = (value) => value == 42;

vs.

Expression<Func<int, bool>> Is42 = (value) => value == 42;

80voto

Jeff Mercado Points 42075

En stockant un lambda comme un délégué, vous stockez une instance spécifique d'un délégué qui effectue une certaine action. Il ne peut pas être modifié, il suffit de l'appeler. Une fois que vous avez votre délégué, vous avez des options limitées pour inspecter ce qu'il fait et ainsi de suite.

En stockant un lambda sous forme d'expression, vous stockez un arbre d'expression qui représente le délégué. Il peut être manipulé pour faire d'autres choses comme changer ses paramètres, changer le corps et lui faire faire quelque chose de radicalement différent. Elle peut même être compilée en un délégué pour que vous puissiez l'appeler si vous le souhaitez. Vous pouvez facilement inspecter l'expression pour voir quels sont ses paramètres, ce qu'elle fait et comment elle le fait. C'est quelque chose qu'un fournisseur de requêtes peut utiliser pour comprendre et traduire une expression dans un autre langage (comme écrire une requête SQL pour un arbre d'expression correspondant).

Il est également beaucoup plus facile de créer un délégué de manière dynamique en utilisant des expressions que d'émettre le code. Vous pouvez considérer votre code à un niveau supérieur comme des expressions, ce qui est très similaire à la façon dont un compilateur voit le code, au lieu d'aller à un niveau inférieur et de voir votre code comme des instructions IL.

Ainsi, avec une expression, vous êtes capable de faire beaucoup plus qu'un simple délégué anonyme. Bien que ce ne soit pas vraiment gratuit, les performances seront affectées si vous exécutez des expressions compilées par rapport à une méthode ordinaire ou un délégué anonyme. Mais ce n'est peut-être pas un problème, car les autres avantages de l'utilisation des expressions peuvent être importants pour vous.

17voto

Tim Rogers Points 9956

Func<> est juste un type de délégué. Une expression est une représentation à l'exécution de l'arbre complet de opérations qui, facultativement, peut être compilé au moment de l'exécution dans un délégué. C'est cet arbre qui est analysé par les analyseurs d'expression comme Linq-to-SQL pour générer des instructions SQL ou faire d'autres choses intelligentes. Lorsque vous assignez un lambda à un type Expression, le compilateur génère cet arbre d'expression ainsi que le code IL habituel. En savoir plus sur les arbres d'expression .

14voto

Ucodia Points 1977

Pour illustrer d'autres réponses, si vous compilez ces 2 expressions et que vous regardez le code généré par le compilateur, voici ce que vous verrez :

Func<int, bool> Is42 = (value) => value == 42;

Func<int, bool> Is42 = new Func<int, bool>((@value) => value == 42);

Expression<Func<int, bool>> Is42 = (value) => value == 42;

ParameterExpression[] parameterExpressionArray;
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "value");
Expression<Func<int, bool>> Is42 = Expression.Lambda<Func<int, bool>>(Expression.Equal(parameterExpression, Expression.Constant(42, typeof(int))), new ParameterExpression[] { parameterExpression });

6 votes

Il demandait quelles étaient les différences et le code généré était explicite sur ces différences.

5voto

Nicholas Butler Points 12630

Arbres d'expression vous permettent d'inspecter le code à l'intérieur de l'expression, dans votre code.

Par exemple, si vous avez passé cette expression : o => o.Name votre code pourrait découvrir que le Name était accessible à l'intérieur de l'expression.

4voto

Jakub Konecki Points 28852

Fournit la classe de base à partir de laquelle les classes qui représentent les les nœuds de l'arbre d'expression sont dérivées.

System.Linq.Expressions.BinaryExpression
System.Linq.Expressions.BlockExpression
System.Linq.Expressions.ConditionalExpression
System.Linq.Expressions.ConstantExpression
System.Linq.Expressions.DebugInfoExpression
System.Linq.Expressions.DefaultExpression
System.Linq.Expressions.DynamicExpression
System.Linq.Expressions.GotoExpression
System.Linq.Expressions.IndexExpression
System.Linq.Expressions.InvocationExpression
System.Linq.Expressions.LabelExpression
System.Linq.Expressions.LambdaExpression
System.Linq.Expressions.ListInitExpression
System.Linq.Expressions.LoopExpression
System.Linq.Expressions.MemberExpression
System.Linq.Expressions.MemberInitExpression
System.Linq.Expressions.MethodCallExpression
System.Linq.Expressions.NewArrayExpression
System.Linq.Expressions.NewExpression
System.Linq.Expressions.ParameterExpression
System.Linq.Expressions.RuntimeVariablesExpression
System.Linq.Expressions.SwitchExpression
System.Linq.Expressions.TryExpression
System.Linq.Expressions.TypeBinaryExpression
System.Linq.Expressions.UnaryExpression

http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx

L'arbre d'expression représente l'expression linq qui peut être analysée et par exemple transformée en requête SQL.

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