Passer une arborescence d'expression en tant que paramètre à une autre arborescence d'expression

c# expression-trees lambda

Question

J'ai deux arbres d'expression définis comme ceci:

private Expression<Func<TEntity, TPropertyResult>> PropertyAccessor { get; set; }

et

private Expression<Func<TEntity, TPropertyResult>> PropertyAccessor { get; set; }

J'ai besoin de créer un nouvel arbre d'expression qui donnera l'équivalent de:

private Expression<Func<TEntity, TPropertyResult>> PropertyAccessor { get; set; }

Lorsque Expression.Invoke(this.TestExpression, this.PropertyAccessor) , le Expression.Invoke(this.TestExpression, this.PropertyAccessor) erreur suivant Expression.Invoke(this.TestExpression, this.PropertyAccessor)

{"L'expression de type 'System.Func`2 [MyEntity, System.String]' ne peut pas être utilisée pour le paramètre de type 'System.String'"}

TPropertyResult est une chaîne lors de mon test.

J'ai essayé d'utiliser Expression.Call ou Expression.Invoke . Pas de chance. Que devrais-je utiliser?

Réponse acceptée

Je pense que cela fait ce que vous demandez:

Expression<Func<TEntity, bool>> Combined
{
    get
    {
        var entity = Expression.Parameter(typeof(TEntity));
        var pa = Expression.Invoke(PropertyAccessor, entity);
        var te = Expression.Invoke(TestExpression, pa);
        return (Expression<Func<TEntity, bool>>) Expression.Lambda(te, entity);
    }
}

J'ai testé cela et cela fonctionne comme je m'y attendais.

Cependant, en relisant votre question initiale (avant mes modifications), je commence à avoir l’impression que vous avez posé la mauvaise question et que vous n’avez probablement pas besoin d’arbres d’expression. Si vous avez uniquement besoin de fonctions , vous pouvez les utiliser sans Expression :

Expression<Func<TEntity, bool>> Combined
{
    get
    {
        var entity = Expression.Parameter(typeof(TEntity));
        var pa = Expression.Invoke(PropertyAccessor, entity);
        var te = Expression.Invoke(TestExpression, pa);
        return (Expression<Func<TEntity, bool>>) Expression.Lambda(te, entity);
    }
}

Exemple d'utilisation:

Expression<Func<TEntity, bool>> Combined
{
    get
    {
        var entity = Expression.Parameter(typeof(TEntity));
        var pa = Expression.Invoke(PropertyAccessor, entity);
        var te = Expression.Invoke(TestExpression, pa);
        return (Expression<Func<TEntity, bool>>) Expression.Lambda(te, entity);
    }
}



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