我有课:
public class Uid
{
public Guid Id { get; set; }
}
我有一个表达:
void TestMethod<T, TUid>(Expression<Func<T,IUid>> exp1) where TUid : Uid
{
....
}
我知道exp1.Body
是一个PropertyExpression,它是这样的:(s) => s.UidProperty
其中UidProperty
是Uid类型的属性。拥有它我应该创建以下表达式:
Expression<Func<T, Guid>> myExp = (s) => s.UidProperty.Id
怎么做?
答案 0 :(得分:3)
我们可以使用以下Compose
方法来获取计算值的表达式,以及使用该输出类型作为其输入类型的另一个表达式来创建表达式,该表达式表示如果结果为第一个表达式传递给第二个表达式:
public static Expression<Func<TFirstParam, TResult>>
Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first,
Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
这允许我们写:
public Expression<Func<T, Guid>> TestMethod<T, TUid>(
Expression<Func<T,IUid>> expression)
where TUid : Uid
{
return expression.Compose(uid => uid.Id);
}