我希望防止重复ORM中用于连接/关联两端的相同谓词逻辑。我应该:
1)使用Func<T1, T2, bool>,使用扩展方法获取表达式:
public static Expression<Func<T1, T2, bool>> ExpressionFuncT1T2<T1, T2>(this Func<T1, T2, bool> func) => (t1, t2) => func(t1, t2);
public static Expression<Func<T2, T1, bool>> ExpressionFuncT2T1<T1, T2>(this Func<T1, T2, bool> func) => (t1, t2) => func(t2, t1);或
2)一边使用Expression<Func<T1, T2, bool>>,然后根据这个stackoverflow question答案将其转换为Expression<Func<T2, T1, bool>>,如下所示:
public static Expression<Func<T2, T1, bool>> WhatToCallThis<T1,T2>(
this Expression<Func<T1, T2, bool>> predicate) {
var t1 = Expression.Parameter(typeof(T1), "t1");
var t2 = Expression.Parameter(typeof(T2), "t2");
return Expression.Lambda<Func<T2, T1, bool>>(
Expression.Invoke(predicate,
Expression.PropertyOrField(t2, "T1"),
Expression.PropertyOrField(t1, "T2")
), t2, t1);
}另外,你会给这个方法起什么名字?
发布于 2019-12-18 07:56:05
下面的三种方法似乎都有效,但是哪种方法最适合使用性能明智的方法呢?
使用Expression.Lambda的SwapParameters1
public static Expression<Func<T2, T1, TResult>> SwapParameters1<T1, T2, TResult>
(this Expression<Func<T1, T2, TResult>> exprFunc)
=> Expression.Lambda<Func<T2, T1, TResult>>(exprFunc.Body
, exprFunc.Parameters[1]
, exprFunc.Parameters[0]);使用.Compile()的SwapParameters2:
public static Expression<Func<T2, T1, TResult>> SwapParameters2<T1, T2, TResult>
(this Expression<Func<T1, T2, TResult>> exprFunc)
=> (t1, t2) => exprFunc.Compile()(t2, t1);使用ExpressionVisitor替换参数的SwapParameters3 (此so问题有帮助):
public static Expression<Func<T2, T1, TResult>> SwapParameters3<T1, T2, TResult>
(this Expression<Func<T1, T2, TResult>> exprFunc) {
var param1 = Expression.Parameter(typeof(T1));
var param2 = Expression.Parameter(typeof(T2));
return Expression.Lambda<Func<T2, T1, TResult>>(exprFunc.Body
.Replace(exprFunc.Parameters[0], param1)
.Replace(exprFunc.Parameters[1], param2)
, param1, param2);
}
public static Expression<Func<TNewParam, TResult>> ReplaceParameter<TNewParam, TOldParam, TResult>
(this Expression<Func<TOldParam, TResult>> expression)
where TNewParam : TOldParam {
var param = Expression.Parameter(typeof(TNewParam));
return Expression.Lambda<Func<TNewParam, TResult>>(
expression.Body.Replace(expression.Parameters[0], param)
, param);
}
public 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) => node == from ? to : base.Visit(node);
}
public static Expression Replace(this Expression expression, Expression searchExpression, Expression replaceExpression)
=> new ReplaceVisitor(searchExpression, replaceExpression).Visit(expression);我倾向于使用SwapParameters1。
https://stackoverflow.com/questions/51866404
复制相似问题