Action génératrice <T> avec des expressions comme des chaînes

c# dynamic expression-trees

Question

J'essaie de comprendre comment générer une action à partir d'une collection de chaînes. Les lignes représentent les actions "déclaration" ...

using System.Linq.Dynamic;

Action<T> BuildAction<T>(T sourceObject, T destinationObject) where T : BaseThing
{
    var source = Expression.Parameter(sourceObject.GetType(), "source");
    var destination = Expression.Parameter(destinationObject.GetType(), "destination");

    var statements = new[] {
        "destination.Foo = source.Foo",
        "destination.X = source.Y"
    };

    var parsedStatements = statements.Select(s => DynamicExpression.Parse(new[] { destination, source }, typeof(void), s);

    return Expression.Lambda<Action<T>>(Expression.Block(parsedStatements));
}

L'idée est de se retrouver avec quelque chose comme ...

using System.Linq.Dynamic;

Action<T> BuildAction<T>(T sourceObject, T destinationObject) where T : BaseThing
{
    var source = Expression.Parameter(sourceObject.GetType(), "source");
    var destination = Expression.Parameter(destinationObject.GetType(), "destination");

    var statements = new[] {
        "destination.Foo = source.Foo",
        "destination.X = source.Y"
    };

    var parsedStatements = statements.Select(s => DynamicExpression.Parse(new[] { destination, source }, typeof(void), s);

    return Expression.Lambda<Action<T>>(Expression.Block(parsedStatements));
}

Mon autre problème est que la source et la destination ne doivent pas nécessairement être du même type, elles ne partagent qu'un type de base. Dans cet exemple, la destination peut ne pas avoir de propriété Y et la source peut ne pas avoir de propriété X (car le mapping )

Une mise à jour

Donc, j'ai une solution partielle, bien que cela fasse une tonne d'hypothèses que je veux supprimer et que cela mappe uniquement {destination} .Foo = {source} .Les types de type Bar ne peuvent pas approfondir pour le moment, j'ai pensé que cela pourrait aidez les autres à déterminer où je veux en venir et aidez-moi ainsi à trouver une solution plus complète ...

Donc, comme je l'explique dans les commentaires, il s'agit d'un petit morceau du fonctionnement de mon moteur de flux de travail. L'idée est d'exécuter des activités, puis dans le moteur interne, il génère cette action pour copier les valeurs calculées dans l'activité suivante avant exécution.

J'ai cette struct ...

using System.Linq.Dynamic;

Action<T> BuildAction<T>(T sourceObject, T destinationObject) where T : BaseThing
{
    var source = Expression.Parameter(sourceObject.GetType(), "source");
    var destination = Expression.Parameter(destinationObject.GetType(), "destination");

    var statements = new[] {
        "destination.Foo = source.Foo",
        "destination.X = source.Y"
    };

    var parsedStatements = statements.Select(s => DynamicExpression.Parse(new[] { destination, source }, typeof(void), s);

    return Expression.Lambda<Action<T>>(Expression.Block(parsedStatements));
}

Ce qui est retourné par "SourceInfoFor (activity, p)" dans le code ci-dessous, le bloc select étant la cause première de ma question ...

using System.Linq.Dynamic;

Action<T> BuildAction<T>(T sourceObject, T destinationObject) where T : BaseThing
{
    var source = Expression.Parameter(sourceObject.GetType(), "source");
    var destination = Expression.Parameter(destinationObject.GetType(), "destination");

    var statements = new[] {
        "destination.Foo = source.Foo",
        "destination.X = source.Y"
    };

    var parsedStatements = statements.Select(s => DynamicExpression.Parse(new[] { destination, source }, typeof(void), s);

    return Expression.Lambda<Action<T>>(Expression.Block(parsedStatements));
}

Notez s'il vous plaît

Pour le facteur de forme que la pile exige de nous lorsque nous posons une question, j’estimais que le fait de poser tout mon problème était un problème beaucoup plus important; .

J'aime aussi et veux une compréhension plus profonde des arbres d'expression!

Réponse acceptée

Il s'est donc avéré que la réponse à cette question n'était pas aussi simple que je l'avais espéré. En bref ... je dois écrire un analyseur d'expression.

Pour le cas le plus simple (celui posé dans la question), je peux utiliser le code dans ma solution partielle, mais pour la solution complète, je vais devoir créer un analyseur syntaxique d'expression capable de gérer beaucoup plus de complexité que les chaînes. .

Dans mon cas, l’utilisation de dictionnaires ou d’approches similaires ne résout qu’une partie du problème sous-jacent, et je ne peux pas utiliser la réflexion parce que ma situation justifie une "réutilisation de l’action compilée à grande échelle" (que j’avais légèrement évoquée dans la question).

Je pourrais me référer à une liste de questions avec des réponses permettant de résoudre divers problèmes, mais j’ai réussi à trouver un point de départ plus "complet" pour ce que j’essayais de réaliser ailleurs ...

https://archive.codeplex.com/?p=simproexpr

... cet exemple peut faire un peu plus que simplement analyser des expressions, il est également capable d'analyser des blocs d'expression.

En utilisant cela / quelque chose comme ça, je vais construire quelque chose dans ce sens pour résoudre mon problème, j'espère que cela aidera les autres.




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