Je suis l'idiot dans ce scénario.
J'ai essayé de lire sur Google ce que c'est, mais je ne comprends pas. Quelqu'un peut-il me donner une explication simple de ce qu'ils sont et de leur utilité ?
edit : je parle de la fonction LINQ dans .Net.
Je suis l'idiot dans ce scénario.
J'ai essayé de lire sur Google ce que c'est, mais je ne comprends pas. Quelqu'un peut-il me donner une explication simple de ce qu'ils sont et de leur utilité ?
edit : je parle de la fonction LINQ dans .Net.
Un arbre d'expression est un mécanisme permettant de traduire un code exécutable en données. En utilisant un arbre d'expression, vous pouvez produire une structure de données qui représente votre programme.
En C#, vous pouvez travailler avec l'arbre d'expression produit par les expressions lambda en utilisant la fonction Expression<T>
classe.
Dans un programme traditionnel, vous écrivez un code comme celui-ci :
double hypotenuse = Math.Sqrt(a*a + b*b);
Ce code fait en sorte que le compilateur génère une affectation, et c'est tout. Dans la plupart des cas, c'est tout ce qui compte.
Avec un code conventionnel, votre application ne peut pas revenir rétroactivement en arrière et examiner les éléments suivants hypotenuse
pour déterminer qu'il a été produit en effectuant une Math.Sqrt()
Ces informations ne font tout simplement pas partie du contenu de l'appel.
Considérons maintenant une expression lambda comme la suivante :
Func<int, int, double> hypotenuse = (a, b) => Math.Sqrt(a*a + b*b);
C'est un peu différent de ce qui s'est passé auparavant. Aujourd'hui hypotenuse
est en fait une référence à un bloc de code exécutable . Si vous appelez
hypotenuse(3, 4);
vous obtiendrez la valeur 5
a été renvoyée.
Nous pouvons utiliser arbres d'expression pour explorer le bloc de code exécutable qui a été produit. Essayez plutôt ceci :
Expression<Func<int, int, int>> addTwoNumbersExpression = (x, y) => x + y;
BinaryExpression body = (BinaryExpression) addTwoNumbersExpression.Body;
Console.WriteLine(body);
Cela produit :
(x + y)
Des techniques et des manipulations plus avancées sont possibles avec les arbres d'expression.
Les arbres d'expression sont une représentation en mémoire d'une expression, par exemple une expression arithmétique ou booléenne. Par exemple, considérons l'expression arithmétique
a + b*2
Étant donné que * a une priorité d'opérateur supérieure à +, l'arbre d'expression est construit de cette manière :
[+]
/ \
a [*]
/ \
b 2
Avec cet arbre, l'expression peut être évaluée pour n'importe quelle valeur de a et b. De plus, vous pouvez le transformer en d'autres arbres d'expression, par exemple pour dériver l'expression.
Lorsque vous implémentez un arbre d'expression, je vous suggère de créer une classe de base Expression . A partir de là, la classe Expression binaire serait utilisé pour toutes les expressions binaires, telles que + et * . Vous pourriez ensuite introduire un Expression de référence variable pour référencer des variables (telles que a et b), et une autre classe Expression constante (pour les 2 de l'exemple).
Dans de nombreux cas, l'arbre d'expression est construit à la suite de l'analyse d'une entrée (provenant directement de l'utilisateur ou d'un fichier). Pour évaluer l'arbre d'expression, je suggère d'utiliser la fonction Modèle de visiteur .
Réponse courte : Il est agréable de pouvoir écrire le même type de requête LINQ et de la diriger vers n'importe quelle source de données. Il n'est pas possible d'avoir une requête "intégrée au langage" sans cela.
Réponse longue : Comme vous le savez probablement, lorsque vous compilez un code source, vous le transformez d'un langage à un autre. Généralement d'un langage de haut niveau (C#) à un langage de niveau inférieur (IL).
Il y a essentiellement deux façons de procéder :
C'est ce que font tous les programmes que nous appelons "compilateurs".
Une fois que vous avez un arbre d'analyse, vous pouvez facilement le traduire dans n'importe quel autre langage et c'est ce que les arbres d'expression nous permettent de faire. Comme le code est stocké sous forme de données, vous pouvez lui faire tout ce que vous voulez, mais vous voudrez probablement le traduire dans un autre langage.
Dans LINQ to SQL, les arbres d'expression sont transformés en commande SQL, puis envoyés par câble au serveur de base de données. Pour autant que je sache, ils ne font rien de vraiment sophistiqué lors de la traduction du code, mais ils pourrait . Par exemple, le fournisseur de requêtes pourrait créer un code SQL différent en fonction des conditions du réseau.
IIUC, un arbre d'expression est similaire à un arbre syntaxique abstrait, mais une expression ne contient généralement qu'une seule valeur, alors qu'un AST peut représenter un programme entier (avec des classes, des paquets, des fonctions, des instructions, etc.)
Quoi qu'il en soit, pour une expression (2 + 3) * 5, l'arbre est :
*
/ \
+ 5
/ \
2 3
Évaluer chaque nœud de manière récursive (de bas en haut) pour obtenir la valeur du nœud racine, c'est-à-dire la valeur de l'expression.
Vous pouvez bien sûr avoir des opérateurs unaires (négation) ou trinaires (if-then-else), ainsi que des fonctions (n-aires, c'est-à-dire un nombre quelconque d'opérations) si votre langage d'expression le permet.
L'évaluation des types et le contrôle des types s'effectuent sur des arbres similaires.
Le DLR
Les arbres d'expression ont été ajoutés à C# pour prendre en charge le Dynamic Language Runtime (DLR). Le DLR est également à l'origine de la méthode "var" de déclaration des variables. ( var objA = new Tree();
)
Essentiellement, Microsoft voulait ouvrir le CLR aux langages dynamiques, tels que LISP, SmallTalk, Javascript, etc. Pour ce faire, il fallait pouvoir analyser et évaluer les expressions à la volée. Cela n'était pas possible avant l'apparition du DLR.
Pour en revenir à ma première phrase, les arbres d'expression sont un ajout à C# qui permet d'utiliser le DLR. Avant cela, C# était un langage beaucoup plus statique - tous les types de variables devaient être déclarés comme un type spécifique et tout le code devait être écrit au moment de la compilation.
L'utiliser avec des données
Les arbres d'expression ouvrent les portes du code dynamique.
Supposons, par exemple, que vous créiez un site immobilier. Pendant la phase de conception, vous connaissez tous les filtres que vous pouvez appliquer. Pour mettre en œuvre ce code, vous avez deux possibilités : vous pouvez écrire une boucle qui compare chaque point de données à une série de vérifications If-Then ; ou vous pouvez essayer de construire une requête dans un langage dynamique (SQL) et la transmettre à un programme qui peut effectuer la recherche pour vous (la base de données).
Avec les arbres d'expression, vous pouvez désormais modifier le code de votre programme - à la volée - et effectuer la recherche. Plus précisément, vous pouvez le faire par le biais de LINQ.
(Voir plus : MSDN : Comment : Utiliser les arbres d'expression pour construire des requêtes dynamiques ).
Au-delà des données
Les arbres d'expression sont principalement utilisés pour la gestion des données. Cependant, ils peuvent également être utilisés pour le code généré dynamiquement. Ainsi, si vous voulez une fonction définie dynamiquement (comme en Javascript), vous pouvez créer un arbre d'expression, le compiler et évaluer les résultats.
J'irais bien plus loin, mais ce site fait un bien meilleur travail :
Les arbres d'expression comme compilateur
Les exemples cités comprennent la création d'opérateurs génériques pour les types de variables, le déroulement manuel des expressions lambda, le clonage peu profond à haute performance et la copie dynamique des propriétés en lecture/écriture d'un objet à un autre.
Résumé
Les arbres d'expression sont des représentations du code qui est compilé et évalué au moment de l'exécution. Ils permettent d'utiliser des types dynamiques, ce qui est utile pour la manipulation de données et la programmation dynamique.
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.