Expression Tree et méthode Compile

c# expression-trees lambda

Question

Il s’agit de la méthode Compile du type d’ Expression . Désolé d'être naïf depuis mon arrivée tardive. Je lisais sur la construction d'expression afin de permettre la modification dynamique du code exécutable. Et cela a du sens pour moi quand il s'agit d'émettre une expression lambda à partir d'un arbre d'expression donné aussi longtemps que les entrées / l'environnement varient (disons pour des valeurs différentes pour toute expression constante / paramètre / membre donnée). Je suppose que ce serait idéal si je pouvais mettre en cache (réutiliser) lambda ceux qui sont générés / compilés à partir d’un arbre d’expression pourvu qu’il n’y ait aucun changement dans l’environnement.

Question : Est-ce que CLR émet toujours une expression lambda même si je n’ai pas changé d’environnement? Si tel est le cas, quel est le meilleur moyen d'éviter la compilation d'expression de lambda s'il n'y a pas de changement dans l'environnement?

Réponse acceptée

Les expressions Lambda sont juste un moyen de représenter un morceau de code: appelez ceci, appelez cela, comparez ces arguments, retournez quelque chose, etc. Presque de la même manière que vous le faites depuis l'éditeur de code, ou JIT depuis IL.

Compile émet un délégué à partir d'une expression lambda particulière. Une fois que vous avez compilé lambda en délégué, le délégué reste inchangé (le lambda reste inchangé, car il est immuable).

Cela ne signifie pas que ce délégué ne peut accepter aucun argument ni appeler aucune méthode d'aucun objet. Cela signifie simplement que la IL de ce délégué ne change pas. Et oui, vous pouvez mettre en cache l’instance de délégué compilée.


Réponse populaire

CLR ne met pas en cache les expressions lambda, Compile() renvoie à chaque fois un nouveau délégué.

Mais il devrait être facile de mettre en cache, via quelque chose comme:

public Func<T> Get<T>(Expression<Func<T>> expression)
{
    string key = expression.Body.ToString();

    Func<T> result;
    if (!_cache.TryGetValue(key, out result)) {
        result = expression.Compile();
        _cache.Add(key, result);
    }

    return result;
}


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow