【问题标题】:Custom IComparer in LINQ OrderBy Lambda expressionLINQ OrderBy Lambda 表达式中的自定义 IComparer
【发布时间】:2014-03-05 17:52:33
【问题描述】:

我有一个要与 OrderBy 一起使用的自定义比较器。我正在尝试构建一个 LINQ 表达式以使其工作。所以本质上,我正在尝试将 IComparer、OrderBy inLinq 表达式放在一起。

我尝试构建的表达式应该类似于:

source => source.OrderBy(lambdaParameter => lambdaParameter.Name, new Parsers.NumericComparer()). 

用表达式下面的代码

'{source => source.OrderBy(lambdaParameter => lambdaParameter.Name)}' 

已构建,我正在尝试将此自定义 Icomparable 添加到此表达式

new Parsers.NumericComparer(). 

这是因为我需要进行自然排序。有人可以帮助我如何包含这个表达式。在过去的几个小时里,我试图阅读几个线程,但我对 LINQ 表达式的理解还不够好,无法实现这一点。谢谢!

private void CreateOrderByMethod(PropertyDescriptor prop, string orderByMethodName, string cacheKey)
{
    /*
     Create a generic method implementation for IEnumerable<T>.
     Cache it.
    */
    var sourceParameter = Expression.Parameter(typeof(List<T>), "source");
    var lambdaParameter = Expression.Parameter(typeof(T), "lambdaParameter");

    var accesedMember = typeof(T).GetProperty(prop.Name);
    var propertySelectorLambda =
        Expression.Lambda(Expression.MakeMemberAccess(lambdaParameter, accesedMember), lambdaParameter);

    var orderByMethod = typeof(Enumerable).GetMethods()
                                  .Where(a => a.Name == orderByMethodName &&
                                               a.GetParameters().Length == 2)
                                  .Single()
                                  .MakeGenericMethod(typeof(T), prop.PropertyType);
    var orderByExpression = Expression.Lambda<Func<List<T>, IEnumerable<T>>>(
                                Expression.Call(orderByMethod,
                                        new Expression[] { sourceParameter, 
                                                       propertySelectorLambda }),
                                        sourceParameter);
    cachedOrderByExpressions.Add(cacheKey, orderByExpression.Compile());
}

【问题讨论】:

    标签: linq lambda expression-trees


    【解决方案1】:

    要创建一个创建对象新实例的表达式,请使用Expression.New

    var newParser = Expression.New(typeof(Parsers.NumericComparer));
    

    那我建议你改用Expression.Call这个重载,这样你就不用去手动抓取MethodInfo了:

    var orderByCall = Expression.Call(
        typeof(Enumerable),
        "OrderBy",
        new [] { typeof(T), prop.PropertyType },
        sourceParameter, propertySelectorLambda, newParser);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多