在C#中使用LINQ select作为方法参数

时间:2015-03-06 11:03:20

标签: c# linq lambda expression

我正在尝试为HTML表格构建创建一个通用方法。

作为我需要的功能的一部分,我希望用户能够指定将转换为列的属性。

由于这是一种通用方法,我原以为用户可以将所需的属性作为某种LINQ表达式传递,并从中我将这个选择应用于数据集,并循环遍历属性以构建表格数据:

  public static string BuildCollapsibleHtmlTable<T>(
        IEnumerable<T> dataSet,
        Func<T, object> tableDataColumnDefinitions,
        KeyValuePair<string, string>[] tableColumnNames,
        Func<T, object> groupByQuery,
        Func<T, decimal> groupSumQuery) where T : class, new() {

      ... implementation ..
   }

&#39; tableColumnDefinitions&#39;部分是我挣扎的地方(第二个参数)。我可以将其用于分组和求和,但不能用于选择要在表中使用的列/属性:

var test = HtmlBuilders.BuildCollapsibleHtmlTable<Client>(
               Model.Clients,
               (clients => clients.ClientName),
               new KeyValuePair<string, string>[] { 
                   new KeyValuePair<string, string> ("Client", "tdCSSLeft"),
                   new KeyValuePair<string, string> ("Debt", "tdCSSCenter")
                },
               (client => client.ClientName),
               (client => client.TotalDebt)
           );

我似乎只能让它一次性拉动一个属性(因此我需要一个表达式数组)。我不反对这一点,但我想知道我是否会这样做错了?是否有更简单/更好的方法将任意选择查询作为参数传递?

1 个答案:

答案 0 :(得分:1)

是的,您需要使用数组。请注意,您似乎已经有一个类似的数组:KeyValuePair<string, string>[] tableColumnNames,所以我看不出问题所在。

从技术上讲,您可以通过以下方式更改方法的签名:

public static string BuildCollapsibleHtmlTable<T>(
    IEnumerable<T> dataSet,
    KeyValuePair<string, string>[] tableColumnNames,
    Func<T, object> groupByQuery,
    Func<T, decimal> groupSumQuery,
    params Func<T, object>[] tableDataColumnDefinitions
) where T : class, new() {

这样您在调用方法时就不需要创建数组,但可以像

一样调用它
var test = HtmlBuilders.BuildCollapsibleHtmlTable<Client>(
           Model.Clients,
           //new KeyValuePair<string, string>[] { 
           new[] {  // Shorter
               new KeyValuePair<string, string> ("Client", "tdCSSLeft"),
               new KeyValuePair<string, string> ("Debt", "tdCSSCenter")
           },
           (client => client.ClientName),
           (client => client.TotalDebt),

           // tableDataColumnDefinitions
           (clients => clients.ClientName),
           (clients => clients.ClientSurname),
           (clients => clients.ClientAddress)
       );