L'arbre d'expression peut être considéré comme l'un des cœurs de Linq. Pourquoi est-il l'un des cœurs de Linq ? Étant donné que l'arborescence d'expression fait que C# ne se contente plus de compiler en IL, nous pouvons générer une arborescence d'expression via C#, utiliser le résultat comme format intermédiaire et le convertir dans le langage natif sur la plate-forme cible. Tel que SQL. C'est ainsi que notre Linq to SQL couramment utilisé génère du SQL.
L'arbre d'expression a été introduit après .NET 3.5. Il s'agit d'un outil puissant et flexible (comme celui utilisé pour construire des requêtes dynamiques dans LINQ).
Jetons d'abord un œil à l'interface API de la classe Expression :
namespace System.Linq.Expressions { // // 摘要: // 以表达式目录树的形式将强类型 lambda 表达式表示为数据结构。此类不能被继承。 // // 类型参数: // TDelegate: // System.Linq.Expressions.Expression`1 表示的委托的类型。 public sealed class Expression<TDelegate> : LambdaExpression { // // 摘要: // 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托。 // // 返回结果: // 一个 TDelegate 类型的委托,它表示由 System.Linq.Expressions.Expression`1 描述的已编译的 lambda 表达式。 public TDelegate Compile(); // // 摘要: // 生成表示 lambda 表达式的委托。 // // 参数: // debugInfoGenerator: // 编译器用于标记序列点并批注局部变量的调试信息生成器。 // // 返回结果: // 包含 lambda 的已编译版本的委托。 public TDelegate Compile(DebugInfoGenerator debugInfoGenerator); // // 摘要: // 创建一个与此表达式类似的新表达式,但使用所提供的子级。如果所有子级都相同,则将返回此表达式。 // // 参数: // body: // 结果的 System.Linq.Expressions.LambdaExpression.Body 属性。 // // parameters: // 结果的 System.Linq.Expressions.LambdaExpression.Parameters 属性。 // // 返回结果: // 此表达式(如果未更改任何子级),或带有更新的子级的表达式。 public Expression<TDelegate> Update(Expression body, IEnumerable<ParameterExpression> parameters); protected internal override Expression Accept(ExpressionVisitor visitor); } }
La syntaxe de l'arbre d'expression est la suivante :
Expression<Func<type,returnType>> = (param) => lamdaexpresion;
Par exemple :
Expression<Func<int, int, int>> expr = (x, y) => x+y;
Nous exécutons le code ci-dessus et visualisons cet arbre d'expression en mode débogage VS :
Vous pouvez constater que l'arbre d'expression est principalement composé des quatre parties suivantes :
1. Partie du corps
2. .Partie Paramètres
3. Type de nœud NodeType
4. , le corps principal est : x+y, les paramètres sont (x, y), NodeType est une expression Lambda et la valeur de retour est int
La partie principale peut être une expression, mais elle ne peut pas contenir d'instructions. Par exemple : je définis un délégué, et l'expression Lambda peut s'écrire comme ceci :
peut aussi s'écrire comme ceci :
Func<int, int, int> func = (x, y) => x + y;
Cependant, dans le type arbre d'expression, seule la première façon d'écrire peut être utilisée. Si la deuxième façon d'écrire est utilisée, une erreur de compilation sera signalée :
Func<int, int, int> func = (x, y) => { return x + y; };
En plus de la manière d'écrire ci-dessus, l'arbre d'expression peut également s'écrire comme ceci :
ParameterExpression pex1 = Expression.Parameter(typeof(int), "x");//第一个参数 ParameterExpression pex2 = Expression.Parameter(typeof(int), "y");//第二个参数 BinaryExpression bexp = Expression.Add(pex1, pex2);//加法 var lambdaExp = Expression.Lambda<Func<int, int, int>>(bexp, new ParameterExpression[] {pex1,pex2 });
En mode débogage VS, vous pouvez voir que les arbres d'expression générés par les deux méthodes d'écriture sont les mêmes
Compilez l'arbre d'expression dans un délégué
LambdaExpression est un type dérivé de Expression . La classe générique Expression
Nous exécutons le code ci-dessus et le résultat est : 4. Nous avons écrit beaucoup de code, qui calculait essentiellement le résultat de 1+3 à l'aide d'un arbre d'expression.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!