如何改进这段排序代码?

6

我正在检查排序参数并编写一堆if语句:

if (sortDirection == "ASC")
{
    if (sortBy == "Id")
        return customerList.OrderBy(x => x.Id).Skip(startIndex).Take(pageSize).ToList();
    if (sortBy == "FirstName")
        return customerList.OrderBy(x => x.FirstName).Skip(startIndex).Take(pageSize).ToList();
    if (sortBy == "City")
        return customerList.OrderBy(x => x.City).Skip(startIndex).Take(pageSize).ToList();
}
else
{
    if (sortBy == "Id")
        return customerList.OrderByDescending(x => x.Id).Skip(startIndex).Take(pageSize).ToList();
    if (sortBy == "FirstName")
        return customerList.OrderByDescending(x => x.FirstName).Skip(startIndex).Take(pageSize).ToList();
    if (sortBy == "City")
        return customerList.OrderByDescending(x => x.City).Skip(startIndex).Take(pageSize).ToList();
}

如何改善这个问题?

6
什么是“更好”?更好的是指什么? - Oded
1
你想要通过什么方式“改进”它呢?它没有按预期工作吗?速度太慢了吗?你不喜欢代码的结构吗?我们需要更多信息。 - Cody Gray
我建议使用LINQ组合。请参见https://dev59.com/j2025IYBdhLWcg3wpXse#5882243 - Euphoric
1
创建一个委托字典,然后根据键调用它们。 - alex
不太熟悉C#语法,但我会尝试使用哈希映射来存储字符串(例如:Id)到对象(例如:x.Id)的关联,并从哈希映射中检索您的orderBy键。 - Philippe
显示剩余2条评论
3个回答

8

将您的订购和查询的其余部分分开 - 对于每个查询相同的部分,您不必在代码库中重复(保持 DRY):

var query = customerList;

if (sortDirection == "ASC")
{
    if (sortBy == "Id")
       query = query.OrderBy(x => x.Id);
    ///and so on
}

query = query.Skip(startIndex).Take(pageSize).ToList();

这仍然是很多样板文件,使用反射会更加简洁。想象一下如果有50个字段! :) - Mathew Thompson
@NiklasB。这将是一个问题,因为OrderBy是通用的,而lambda对于每个属性具有不同的类型。除非您想在任何地方都将其转换为对象。 - Euphoric
@mattytommo:如果这是一个内存集合,那肯定是可行且整洁的。 - BrokenGlass
@Elian:是的,我也是这么想的。函数应该在参数类型上是逆变的,在返回值上是协变的,这似乎在C#中也是这样的情况。 - Niklas B.
@ElianEbbing 我仍然不知道你在LINQ中要如何使用IComparable。请检查OrderBy方法的签名。并非所有地方都需要IComparable。它只需要一个返回值用于比较的函数。而且,即使是IComparable也是具有此属性类型的泛型。也许可以通过实现排序并从函数中返回对象本身来解决问题?这可能有效。 - Euphoric
显示剩余6条评论

2
使用反射 :)
customerList = (sortDirection == "ASC")
   ? customerList
        .OrderBy(x => x.GetType().GetProperty(sortBy).GetValue(x, null))
        .Skip(startIndex)
        .Take(pageSize)
        .ToList()
   : customerList
        .OrderByDescending(x => x.GetType().GetProperty(sortBy).GetValue(x, null))
        .Skip(startIndex)
        .Take(pageSize)
        .ToList();

1

看起来你只是想按属性名称作为字符串排序。在这种情况下,使用“动态LINQ”实际上已经解决了这个问题:

Dynamic LINQ OrderBy on IEnumerable<T>

查看这个问题的答案,它应该为你提供解决问题的示例代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接