首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从<T1,T1,bool>创建Linq表达式<T2,T2,bool>

从<T1,T1,bool>创建Linq表达式<T2,T2,bool>
EN

Stack Overflow用户
提问于 2018-08-16 05:03:16
回答 1查看 109关注 0票数 0

我希望防止重复ORM中用于连接/关联两端的相同谓词逻辑。我应该:

1)使用Func<T1, T2, bool>,使用扩展方法获取表达式:

代码语言:javascript
复制
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>>,如下所示:

代码语言:javascript
复制
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);
    }

另外,你会给这个方法起什么名字?

EN

回答 1

Stack Overflow用户

发布于 2019-12-18 07:56:05

下面的三种方法似乎都有效,但是哪种方法最适合使用性能明智的方法呢?

使用Expression.Lambda的SwapParameters1

代码语言:javascript
复制
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:

代码语言:javascript
复制
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问题有帮助):

代码语言:javascript
复制
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。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51866404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档