Évaluer l'expression lambda dans l'arborescence de l'expression

c# expression-trees lambda

Question

J'essaie de construire une expression lambda en utilisant des arbres d'expression. Voici le format de l'expression lambda que j'essaie de créer:

Func<DateTime, string> requiredLambda = dt =>
    {
        var formattedDate = dt.ToShortDateString();

        /**
        * The logic is not important here - what is important is that I 
        * am using the result of the executed lambda expression.
        * */
        var builder = new StringBuilder();
        builder.Append(formattedDate);
        builder.Append(" Hello!");
        return builder.ToString();
    };

Le problème, c'est que je ne construis pas cet arbre à partir de rien - la logique de formatage m'est déjà transmise sous la forme d'une instance d' Expression<Func<DateTime, string>> - par exemple:

Func<DateTime, string> requiredLambda = dt =>
    {
        var formattedDate = dt.ToShortDateString();

        /**
        * The logic is not important here - what is important is that I 
        * am using the result of the executed lambda expression.
        * */
        var builder = new StringBuilder();
        builder.Append(formattedDate);
        builder.Append(" Hello!");
        return builder.ToString();
    };

Je sais qu'en dehors de l'arbre d'expression, je peux appeler

Func<DateTime, string> requiredLambda = dt =>
    {
        var formattedDate = dt.ToShortDateString();

        /**
        * The logic is not important here - what is important is that I 
        * am using the result of the executed lambda expression.
        * */
        var builder = new StringBuilder();
        builder.Append(formattedDate);
        builder.Append(" Hello!");
        return builder.ToString();
    };

pour évaluer l'expression - mais le problème est que je souhaite l'évaluer et l'affecter dans l'arbre des expressions - me permettant d'effectuer une logique supplémentaire sur le résultat dans l'arbre des expressions.

Rien de ce que j'ai imaginé jusqu'ici ne semble faire le voyage - presque certainement à une incompréhension du fonctionnement des arbres d'expression. Toute aide grandement appréciée!

Réponse acceptée

Donc, si je vous ai bien compris, vous voulez créer une lambda (expression) qui utilise votre fonction passée et effectue un travail supplémentaire autour de celle-ci. Donc, vous voulez essentiellement utiliser cette fonction dans une expression.

À ce stade, permettez-moi de suggérer que vous n'utilisez même pas d'expressions. Vous pouvez simplement créer une fonction qui prend un paramètre Func<DateTime, string> et l’utilise pour traiter quelque chose. Mais au cas où vous auriez vraiment besoin de l'expression pour quelque chose, je vais juste essayer d'expliquer comment en construire une.

Pour cet exemple, je vais créer cette fonction:

string MonthAndDayToString (int month, int day)
{
    return "'" + formattingFunction(new DateTime(2013, month, day)) + "'"
}

Comme vous pouvez le constater, je vais créer un Func<int, int, string> qui crée ensuite l'objet DateTime et le passe à la fonction, puis modifie le résultat.

string MonthAndDayToString (int month, int day)
{
    return "'" + formattingFunction(new DateTime(2013, month, day)) + "'"
}

Après avoir examiné la réponse d’Alex, il semble que j’ai mal compris votre question et que j’ai essayé de résoudre l’inverse de ce que vous faites. Mais ce n'est pas si différent de le changer pour ce que vous essayez réellement de faire:

string MonthAndDayToString (int month, int day)
{
    return "'" + formattingFunction(new DateTime(2013, month, day)) + "'"
}

Mais je soutiendrais toujours qu’une fonction normale prenant Func<DateTime, string> et un paramètre DateTime serait beaucoup plus facile à gérer. Donc, à moins que vous n'ayez vraiment besoin d' expressions, évitez-les.


Pourquoi je ne pense toujours pas que vous ayez vraiment besoin d'expressions pour cela. Considérons cet exemple:

string MonthAndDayToString (int month, int day)
{
    return "'" + formattingFunction(new DateTime(2013, month, day)) + "'"
}

Comme vous pouvez le constater, je ne construis qu'une seule fois la fonction de logique de formatage, paresseusement lorsqu'elle n'est pas encore définie. C'est à ce moment-là que la réflexion s'exécute pour obtenir certaines valeurs que vous utilisez quelque part dans la fonction. Lorsque la fonction est créée en tant que fonction lambda, les variables que nous utilisons à partir de la portée locale dans la fonction lambda sont automatiquement capturées et maintenues disponibles.

Maintenant, bien sûr, vous pouvez également créer ceci comme une expression et stocker la fonction compilée, mais je dirais que le faire comme ceci est beaucoup plus lisible et maintenable.


Réponse populaire

Vous pouvez utiliser:

Func<Func<DateTime,string>, DateTime, string> requiredLambda = (f, dt) =>
{
    var formattedDate = f.Invoke(dt);

    /**
    * The logic is not important here - what is important is that I 
    * am using the result of the executed lambda expression.
    * */
    var builder = new StringBuilder();
    builder.Append(formattedDate);
    builder.Append(" Hello!");
    return builder.ToString();
};

Ensuite, vous avez votre expression d'entrée:

Func<Func<DateTime,string>, DateTime, string> requiredLambda = (f, dt) =>
{
    var formattedDate = f.Invoke(dt);

    /**
    * The logic is not important here - what is important is that I 
    * am using the result of the executed lambda expression.
    * */
    var builder = new StringBuilder();
    builder.Append(formattedDate);
    builder.Append(" Hello!");
    return builder.ToString();
};

Et le résultat:

Func<Func<DateTime,string>, DateTime, string> requiredLambda = (f, dt) =>
{
    var formattedDate = f.Invoke(dt);

    /**
    * The logic is not important here - what is important is that I 
    * am using the result of the executed lambda expression.
    * */
    var builder = new StringBuilder();
    builder.Append(formattedDate);
    builder.Append(" Hello!");
    return builder.ToString();
};



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi