Impossible de créer une expression composée <Func<string, bool> &gt; à partir d&#39;un ensemble d&#39;expressions

.net c# expression expression-trees

Question

(Réponse vers le bas)

J'essaie de construire un système qui combine

Func<T, bool> 

les délégués dans un ExpressionTree qui me permet de passer une valeur (badValue dans ce cas) et d'obtenir un bool out si les prédicats retournent tous la valeur true et que les opérations binaires sont prises en compte. C’est la première fois que j’utilise Expression / ExpressionTrees. Soyez donc doux.

Je reçois cette erreur:

ArgumentException: une expression de type 'System.Boolean' ne peut pas être invoquée

sur cette ligne:

Func<T, bool> 

Cette ligne est configurée de cette manière car je dois partager la référence à la value entre toutes les expressions (non?).

Mon scénario idéal est d’avoir juste un tas de

Func<T, bool> 

et je peux les transmettre dans un système à côté d'opérateurs logiques (And / Or / Not) et obtenir un résultat final booléen. En espérant permettre la construction dynamique de règles par lesquelles une valeur doit passer.

Est-ce même possible dans l'itinéraire que je vais? Si ce n’est pas le cas, il serait souhaitable que deux personnes me dirigent dans la bonne direction.

Func<T, bool> 

Réponse Je ne poussais par le paramètre (s) de la bonne façon, au- dessous est un exemple de plusieurs paramètres partagés entre plusieurs expressions qui sont mis dans un ExpressionTree et un booléen unique qui sort de la compilé Func, isValid

Func<T, bool> 

Réponse acceptée

Si vous voulez le faire avec Expressions, quelque chose comme ceci fonctionnerait. Cela ne court-circuite pas, bien que vous puissiez l'intégrer. Vous étiez assez proche. Vous devez inclure une expression de paramètre dans toute l'arborescence de paramètres.

string badValue = "hello!";
const int minSize = 8;
const int maxSize = 30;

Expression<Func<string, bool>> stringLengthMax = value => value.Length < maxSize;
Expression<Func<string, bool>> stringLengthMin = value => value.Length > minSize;
Expression<Func<string, bool>> isEmpty = value => !string.IsNullOrEmpty(value);

ParameterExpression pe = Expression.Parameter(typeof(string));

var x = Expression.Lambda<Func<string, bool>>(
    Expression.And(Expression.Invoke(stringLengthMax, pe), 
        Expression.And(Expression.Invoke(stringLengthMin, pe), Expression.Invoke(isEmpty, pe))), pe);

Func<string, bool> shouldValidate = x.Compile();
bool resultFalse1 = shouldValidate("hello!");
bool resultFalse2 = shouldValidate("1234567890123456789012345678901");
//bool resultFalse3 = shouldValidate(null); Throws an exception because you can't do (null).Length
bool shouldBeTrue = shouldValidate("123456789");

//LinqPad code to view results:
resultFalse1.Dump();
resultFalse2.Dump();
//resultFalse3.Dump();
shouldBeTrue.Dump();

Réponse populaire

Il me semble que vous n'avez pas vraiment besoin de créer un arbre d'expression. Vous pouvez combiner vos fonctions avec linq simple (définissez-les comme étant Func<string, bool> , pas Expression<Func<string, bool>> ):

Func<string, bool> shouldValidate = 
    arg => new[] {stringLengthMax, stringLengthMin, isEmpty}.All(func => func(arg));

Si vous voulez utiliser plus que juste and , vous pouvez combiner vos fonctions de manière logique:

Func<string, bool> shouldValidate = 
    arg => new[] {stringLengthMax, stringLengthMin, isEmpty}.All(func => func(arg));



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