从一组对象动态构建lambda表达式?

时间:2018-02-27 23:00:19

标签: c# linq lambda linq-to-objects kendo-ui-mvc

我有以这种格式存储的排序列表:

width

我需要将其转换为public class ReportSort { public ListSortDirection SortDirection { get; set; } public string Member { get; set; } }

类型的lambda表达式

假设我有以下报告排序集合:

Action<DataSourceSortDescriptorFactory<TModel>>

我需要将其转换为这样的语句,如下所示:

new ReportSort(ListSortDirection.Ascending, "LastName"),
new ReportSort(ListSortDirection.Ascending, "FirstName"),

排序方法签名是:

.Sort(sort => { 
        sort.Add("LastName").Ascending();
        sort.Add("FirstName").Ascending();
      })

所以我现在有一些方法:

public virtual TDataSourceBuilder Sort(Action<DataSourceSortDescriptorFactory<TModel>> configurator)

......我不知道该怎么做。

编辑:答案是:

public static Action<DataSourceSortDescriptorFactory<TModel>> ToGridSortsFromReportSorts<TModel>(List<ReportSort> sorts) where TModel : class
    {
        Action<DataSourceSortDescriptorFactory<TModel>> expression;
        //stuff I don't know how to do
        return expression;
    }

我一开始想我必须使用Expression类从头开始动态构建lambda表达式。幸运的是,情况并非如此。

2 个答案:

答案 0 :(得分:5)

  

......我不知道该怎么做。

好吧,推理出来。

你手头有什么? FooJob名为List<ReportSort>

你需要什么? sorts

你已经迈出了第一步:你已经制定了一种方法来接受你拥有的东西并返回你需要的东西。伟大的第一步。

Action<Whatever>

你已经喊出了你不知道该怎么做的事情。这是一种很好的技巧。

首先填写编译但无法正常工作的内容。

    Action<DataSourceSortDescriptorFactory<TModel>> expression;
    //stuff I don't know how to do
    return expression;

优异。 现在您有一个编译程序,这意味着您可以运行测试并验证如果需要这种情况,测试会通过,如果还有其他需要,测试将失败。

现在想想,我手头有什么?我有一份清单,我正在做Action<DataSourceSortDescriptorFactory<TModel>> expression = sort => { sort.Add("LastName").Ascending(); sort.Add("FirstName").Ascending(); }; return expression; 。这意味着副作用正在发生,可能涉及列表中的每个项目。所以那里可能有一个Action

foreach

编译它。它失败。啊,我们已经混淆了我们添加的新排序。解决问题。

Action<DataSourceSortDescriptorFactory<TModel>> expression = 
  sort => {         
    sort.Add("LastName").Ascending();
    sort.Add("FirstName").Ascending();
    foreach(var sort in sorts) { 
      // Do something
    }
  };
return expression;

很好,现在我们再次能够编译并运行测试。

这里的模式应该清楚。 继续编译,继续运行测试,逐步使您的程序越来越正确,理解您可以对手头的值执行的操作。

你能完成它吗?

答案 1 :(得分:1)

您可以使用以下可以分配给Action<T>委托的lambda表达式。在该lambda表达式中,捕获List<T>变量并循环遍历它:

public static Action<DataSourceSortDescriptorFactory<TModel>> ToGridSortsFromReportSorts<TModel>(List<ReportSort> sorts) where TModel : class
{
    Action<DataSourceSortDescriptorFactory<TModel>> expression = 
       result  => 
       {
           foreach (var sort in sorts)
           {
                if (sort.SortDirection == ListSortDirection.Ascending)
                    result.Add(sort.Member).Ascending();
                else // or whatever other methods you want to handle here
                    result.Add(sort.Member).Descending();
           }
       };
    return expression;
}