Bea*_*692 5 c# lambda expression-trees
我们有一个类型的实体,T1它有一个类型的成员T.这样的事情:
public class T1
{
public T Member{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
用户可以使用我们的UI为我们提供一个过滤器,我们已经将它转换为一个函数的表达式,该函数获得一个T并返回bool (Expression<Func<T,bool>>)
我想知道是否可以将其转换为获取T1并返回bool的函数的表达式.
其实我想转换这个:
(t=>t.Member1==someValue && t.Member2==someOtherValue);
Run Code Online (Sandbox Code Playgroud)
对此:
(t1=>t1.Member.Member1==someValue && t1.Member.Member2==someOtherValue);
Run Code Online (Sandbox Code Playgroud)
您可以通过几种方式做到这一点。
第一个也是最简单的:使用Expression.Invoke
Expression<Func<T, bool>> exprT = t.Member1==someValue && t.Member2==someOtherValue
ParameterExpression p = Expression.Parameter(typeof(T1));
var expr = Expression.Invoke(expr, Expression.PropertyOrField(p, "Member"));
Expression<Func<T1, bool>> exprT1 = Expression.Lambda<Func<T1, bool>>(expr, p);
Run Code Online (Sandbox Code Playgroud)
但在这种情况下你不会得到
t1 => (t=>(t.Member1==someValue && t.Member2==someOtherValue))(t1.Member),
Run Code Online (Sandbox Code Playgroud)
代替
(t1=>t1.Member.Member1==someValue && t1.Member.Member2==someOtherValue);
Run Code Online (Sandbox Code Playgroud)
要替换,您可以使用ExpressionVisitor 类,例如
class V : ExpressionVisitor
{
public ParameterExpression Parameter { get; private set; }
Expression m;
public V(Type parameterType, string member)
{
Parameter = Expression.Parameter(parameterType);
this.m = Expression.PropertyOrField(Parameter, member);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Type == m.Type)
{
return m;
}
return base.VisitParameter(node);
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它
var v = new V(typeof(T1), "Member");
var exprT1 = Expression.Lambda<Func<T1, bool>>(v.Visit(exprT.Body), v.Parameter);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1393 次 |
| 最近记录: |