Composition d’invocations avec Expression <Func > de la même manière que Func

Considérons une classe qui peut être utilisée en tant que membre de plusieurs autres classes:

class Customer { public ssortingng FirstName {get;set;} public ssortingng LastName {get;set;} } // Both "Order" and "Profile" have a "Customer" property class Order { public Customer Customer {get;set;} } class Profile { public Customer Customer {get;set;} } 

Je veux définir une méthode qui crée un vérificateur pour un object associé à un Customer . Si je veux un vérificateur en mémoire, je le fais comme ceci:

 static Func Check(Func conv, ssortingng first, ssortingng last) { return obj => conv(obj).FirstName == first && conv(obj).LastName == last; } 

Je peux utiliser mon vérificateur pour les séquences en mémoire comme suit:

 var matchingOrders = orders .Where(Check(x => x.Customer, "Foo", "Bar")) .ToList(); var matchingProfiles = profiles .Where(Check(x => x.Customer, "Foo", "Bar")) .ToList(); 

Maintenant, je veux faire la même chose avec Expression<Func> :

 static Expression<Func> Check(Expression<Func> conv, ssortingng first, ssortingng last) 

Malheureusement, le même truc ne fonctionne pas:

 return obj => conv(obj).FirstName == first && conv(obj).LastName == last; 

et l’utiliser comme ça:

 var matchingOrders = dbContext.Orders .Where(Check(x => x.Customer, "Foo", "Bar")) .ToList(); var matchingProfiles = dbContext.Profiles .Where(Check(x => x.Customer, "Foo", "Bar")) .ToList(); 

Cela déclenche une erreur:

CS0119: l’expression désigne une variable', where a groupe de méthodes’ était attendu

Puis-je composer des expressions de la même manière que je compose des delegates?

Malheureusement, C # ne permet pas actuellement de composer des expressions à partir d’objects Expression> . Vous devez utiliser des arbres d’expression, ce qui est un peu plus long:

 static Expression> CheckExpr(Expression> conv, ssortingng first, ssortingng last) { var arg = Expression.Parameter(typeof(T)); var get = Expression.Invoke(conv, arg); return Expression.Lambda>( Expression.MakeBinary( ExpressionType.AndAlso , Expression.MakeBinary( ExpressionType.Equal , Expression.Property(get, nameof(Customer.FirstName)) , Expression.Constant(first) ) , Expression.MakeBinary( ExpressionType.Equal , Expression.Property(get, nameof(Customer.LastName)) , Expression.Constant(last) ) ) , arg ); }