鉴于类型:
public class MyClass
{
public string Prop { get; set; }
}
和
public class MyWrapper
{
public MyWrapper(MyClass myClass)
{
MyClass = myClass;
}
public MyClass MyClass { get; }
}
是否可以将Expression<Func<MyClass, bool>>
类型的谓词表达式转换为Expression<Func<MyWrapper, bool>>
?
e.g。有这样的方法:
public Expression<Func<MyWrapper, bool>> Convert(Expression<Func<MyClass, bool>> predicate)
{
return ...
}
以便调用Convert(obj => obj.Prop == "ABC")
将返回wrapper => wrapper.MyClass.Prop == "ABC"
答案 0 :(得分:1)
您需要使用ExpressonVisitor访问传入的谓词的主体,并将类型MyClass
的每个参数更改为MyClass
类型的MyWrapper
参数的成员访问权限1}}。最后,您将新构造的主体构造为具有类型MyWrapper
的参数作为参数的新lambda表达式。
访客样本:
public class ConverterVisitor : ExpressionVisitor
{
public ConverterVisitor(ParameterExpression original, Expression convertTo)
{
OriginalParameter = original;
ConvertTo = convertTo;
}
public ParameterExpression OriginalParameter { get; }
public Expression ConvertTo { get; }
protected override Expression VisitParameter(ParameterExpression node)
{
if (OriginalParameter == node)
{
return ConvertTo;
}
return base.VisitParameter(node);
}
}
Convert
方法的示例:
public Expression<Func<MyWrapper, bool>> Convert(Expression<Func<MyClass, bool>> predicate)
{
var originalParameter = predicate.Parameters[0];
var newParameter = Expression.Parameter(typeof(MyWrapper));
var ma = Expression.Property(newParameter, nameof(MyWrapper.MyClass));
var converter = new ConverterVisitor(originalParameter, ma);
var newBody = converter.Visit(predicate.Body);
return Expression.Lambda<Func<MyWrapper, bool>>(newBody, newParameter);
}