作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想合并以下表达式:
// example class
class Order
{
List<OrderLine> Lines
}
class OrderLine { }
Expression<Func<Order, List<OrderLine>>> selectOrderLines = o => o.Lines;
Expression<Func<List<OrderLine>, Boolean>> validateOrderLines = lines => lines.Count > 0;
// now combine those to
Expression<Func<Order, Boolean>> validateOrder;
我使用对 selectOrderLines 的调用并将结果提供给 validateOrderLines 使其工作,但因为我在 Entity Framework 中使用这些表达式,所以我实际上必须创建一个干净的表达式,它应该表示:
Expression<Func<Order, Boolean>> validateOrder = o => o.Lines.Count > 0;
我该怎么做?
最佳答案
最优雅的方法是使用 Expression Visitor .特别是这个 MSDN Blog Entry描述了如何在不调用的情况下使用它来组合谓词(使用 bool 值 And 或 Or)。
已编辑 意识到 bool 组合不是你想要的,我写了一个 ExpressionVisitor 的示例用法来解决你的特定问题:
public class ParameterToMemberExpressionRebinder : ExpressionVisitor
{
ParameterExpression _paramExpr;
MemberExpression _memberExpr;
ParameterToMemberExpressionRebinder(ParameterExpression paramExpr, MemberExpression memberExpr)
{
_paramExpr = paramExpr;
_memberExpr = memberExpr;
}
protected override Expression Visit(Expression p)
{
return base.Visit(p == _paramExpr ? _memberExpr : p);
}
public static Expression<Func<T, bool>> CombinePropertySelectorWithPredicate<T, T2>(
Expression<Func<T, T2>> propertySelector,
Expression<Func<T2, bool>> propertyPredicate)
{
var memberExpression = propertySelector.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("propertySelector");
}
var expr = Expression.Lambda<Func<T, bool>>(propertyPredicate.Body, propertySelector.Parameters);
var rebinder = new ParameterToMemberExpressionRebinder(propertyPredicate.Parameters[0], memberExpression);
expr = (Expression<Func<T, bool>>)rebinder.Visit(expr);
return expr;
}
class OrderLine
{
}
class Order
{
public List<OrderLine> Lines;
}
static void test()
{
Expression<Func<Order, List<OrderLine>>> selectOrderLines = o => o.Lines;
Expression<Func<List<OrderLine>, Boolean>> validateOrderLines = lines => lines.Count > 0;
var validateOrder = ParameterToMemberExpressionRebinder.CombinePropertySelectorWithPredicate(selectOrderLines, validateOrderLines);
// validateOrder: {o => (o.Lines.Count > 0)}
}
}
关于c# - 如何在没有调用的情况下合并两个 C# Lambda 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1131869/
我是一名优秀的程序员,十分优秀!