3

我有以下方法:

private List<TSource> Sort<TSource, TKey>(
    List<TSource> list, 
    Func<TSource, TKey> sorter, 
    SortDirection direction)
{
    ...
}

并且根据情况,参数Func<TSource,TKey>会发生变化,例如,我有以下开关:

public class CustomType
{
    string Name {get; set;}
    string Surname {get; set;}
    ...
}

switch (sortBy)
{
    case "name":
        orderedList = this.Sort<CustomType, string>(
            lstCustomTypes,
            s => s.Name.ToString(),
            direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
        break;
    case "surname":
        orderedList = this.Sort<CustomType, string>(
            lstCustomTypes,
            s => s.Surname.ToString(),
            direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
        break;
   }

因此,正如您在这些情况下所观察到的那样,除了 lambda 参数之外,调用总是相同的s => somethings => something2所以对于没有重复代码,我想要类似于:

switch (sortBy)
{
    case "name":
        lambdaExpresion = s => s.Name.ToString();
        break;
    case "surname":
        lambdaExpresion= s => s.Surname.ToString();
        break;
    }

    orderedList = this.Sort<CustomType, string>(
        lstCustomTypes,
        lambdaExpresion,
        direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);

我不确定是否可能,但如果可以,如何实现?我不想重复代码。

4

6 回答 6

4

是的,您可以将 lambda 分配给一个变量:

Func<CustomType, string> lambda;  
switch (sortBy)
{
    case "name":
        lambda = s => s.Name.ToString();
        break;
    case "surname":
        lambda = s => s.Surname.ToString();
        break;
}

orderedList = this.Sort<CustomType, string>(
    lstCustomTypes,
    lambda,
    direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
于 2013-05-29T18:21:44.567 回答
1

首先声明 lambda 变量:

Func<CustomType, string> lambdaExpresion;

switch声明之前。这是可能的,因为两种情况下的 lambda 类型是相同的;否则不可能。

于 2013-05-29T18:22:17.500 回答
1

您可以定义一个变量来保存您的函数,

Func<CustomType, string> lambdaExpresion;

然后在你的switch块中分配它,就像这样,

switch (sortBy)
{
    case "name":
        lambda = s => s.Name;
        break;
    case "surname":
        lambda = s => s.Surname;
        break;
}
于 2013-05-29T18:22:18.050 回答
0

你基本上已经在那里了:

Func<CustomType, string> lambdaExpresion;
switch (sortBy)
{
    case "name":
        lambdaExpresion = s => s.Name.ToString();
        break;
    case "surname":
        lambdaExpresion = s => s.Surname.ToString();
        break;
    case default: //need a default value for it to be definitely assigned.
        lambdaExpresion  = s => "";
}

orderedList = this.Sort(lstCustomTypes, lambdaExpresion,
    direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);
于 2013-05-29T18:22:37.507 回答
0

好的,以防万一没有人使用反射:)

orderedList = this.Sort<CustomType, string>(
                lstCustomTypes,
                s => s.GetType().GetProperty(sortBy).GetValue(s).Tostring(),
                 direction == "ASC" ? SortDirection.Ascending : SortDirection.Descending);

只需注意不存在的道具或字段,不兼容的名称(例如您可能希望将第一个字母大写)。错误检查作为练习(因为我现在没有一个盒子来测试这个代码)

于 2013-05-29T18:29:46.110 回答
0

你已经得到了正确的答案。但是,也许您应该只使用 OrderBy 和 OrderByDescending 来代替:

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderby.aspx

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderbydescending.aspx

第一个链接的示例:

Pet[] pets = { new Pet { Name="Barley", Age=8 },
   new Pet { Name="Boots", Age=4 },
   new Pet { Name="Whiskers", Age=1 } };

IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);
于 2013-05-29T18:30:25.083 回答