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 ); }