有没有更简洁的方法可以用C#进行排序?

有没有更简洁的方法可以用C#进行排序?,c#,.net,sorting,C#,.net,Sorting,假设我有一个实体,如: public class Car { public string Make { get; set; } public string Model { get; set; } public DateTime ReleaseDate { get; set; } public int NumCreated { get; set; } } 我们正在为我们的站点使用一个简单的MVP架构,其中包含一个视图层(ASP.NET网站、演示者层(C#类库)、逻

假设我有一个实体,如:

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public DateTime ReleaseDate { get; set; }
    public int NumCreated { get; set; }
}
我们正在为我们的站点使用一个简单的MVP架构,其中包含一个视图层(ASP.NET网站、演示者层(C#类库)、逻辑层(C#类库)、数据层(C#类库)

假设我有一个视图,其中显示了一个具有可排序列标题的汽车列表。我过去所做的是在我的逻辑层中进行所有排序,该视图为实体列表需要排序的任何列传递枚举

这是一个痛苦,因为我需要为我拥有的每个实体维护一个枚举,并为实体中的每个属性维护该枚举中的一个条目

例如,我们将做如下工作:

CarLogic.cs

public IEnumerable<Car> GetCarsByYear(string year, SortColumn sortColumn, SortOrder sortOrder)
{
    List<Car> cars = _carRepository.GetCarsByYear(year);  

    switch (sortColumn)
    {
        case SortColumn.Make:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.Make.CompareTo(car2.Make) :
                      car2.Make.CompareTo(car1.Make);
            break;
       case SortColumn.Model:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.Model.CompareTo(car2.Model) :
                      car2.Model.CompareTo(car1.Model);
            break;
       case SortColumn.ReleaseDate:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.ReleaseDate.CompareTo(car2.ReleaseDate) :
                      car2.ReleaseDate.CompareTo(car1.ReleaseDate);
            break;
       case SortColumn.NumCreated:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.NumCreated.CompareTo(car2.NumCreated) :
                      car2.NumCreated.CompareTo(car1.NumCreated);
            break;
       // ...
    }

    return cars;
}
public IEnumerable GetCarsByEAR(字符串年份、SortColumn SortColumn、SortOrder SortOrder)
{
列出车辆=_carRepository.GetCarsByYear(年份);
开关(sortColumn)
{
case SortColumn.Make:
cars.Sort((car1,car2)=>
sortOrder==sortOrder.升序
?car1.制造。比较(car2.制造):
car2.Make.CompareTo(car1.Make);
打破
案例排序列。模型:
cars.Sort((car1,car2)=>
sortOrder==sortOrder.升序
?car1.车型.对比(car2.车型):
car2.Model.CompareTo(car1.Model);
打破
案例SortColumn.ReleaseDate:
cars.Sort((car1,car2)=>
sortOrder==sortOrder.升序
?car1.发布日期。与(car2.发布日期)相比:
car2.发布日期。与(car1.发布日期)相比;
打破
案例SortColumn.num已创建:
cars.Sort((car1,car2)=>
sortOrder==sortOrder.升序
?car1.NumCreated.与(car2.NumCreated)相比:
car2.NumCreated.CompareTo(car1.NumCreated);
打破
// ...
}
返回车辆;
}
这就是我一直在做的。然而,这是一个非常手动的过程,如果一个实体有很多属性,它可能会很烦人


处理此问题的更好方法是什么?是否可以允许我的实体集合在属性上进行排序,而不必按照这样的属性手动执行所有操作?

您可以使用LINQ to对象对实体执行排序

var sortedCars=cars.OrderBy(c=>c.Model)。然后by(c=>c.Make);


或者,您可以使用
OrderByDescending
ThenByDescending
进行描述排序。

更好的处理方法是:

public IEnumerable<Car> GetCarsByYear<T>(string year, SortOrder sortOrder,
    Func<Car, T> fieldSelector) where T : IComparable<T>
{
    List<Car> cars = _carRepository.GetCarsByYear(year);  

    cars.Sort((car1, car2) =>
        sortOrder == sortOrder.Ascending
        ? fieldSelector(car1).CompareTo(fieldSelector(car2)) :
          fieldSelector(car2).CompareTo(fieldSelector(car1)));

    return cars;
}

GetCarsByYear(2010, SortOrder.Ascending,  c => c.Model);
GetCarsByYear(2008, SortOrder.Descending, c => c.Make);
public IEnumerable GetCarsByEAR(字符串年份、排序器排序器、,
Func字段选择器),其中T:i可比较
{
列出车辆=_carRepository.GetCarsByYear(年份);
cars.Sort((car1,car2)=>
sortOrder==sortOrder.升序
?字段选择器(car1)。与字段选择器(car2)相比:
字段选择器(car2)。与字段选择器(car1)进行比较;
返回车辆;
}
GetCarsByYear(2010,SortOrder.Ascending,c=>c.Model);
GetCarsByYear(2008年,排序器下降,c=>c.Make);

正如上面的海报所提到的,使用
OrderBy
而不是将其存储在列表中会更自然一些。

使用类对集合进行排序会更简单吗?

我能想到的最好的方法是使用该方法

    static List<T> SortList<T>(List<T> list, string column)
    {
        foreach (PropertyInfo p in typeof(T).GetProperties())
        {
            if (p.Name == column)
            {
                return list.OrderBy(c => c.GetType().GetProperty(p.Name).GetValue(c, null)).ToList();
            }
        }
        return list;
    }
静态列表排序列表(列表、字符串列)
{
foreach(PropertyInfo p in typeof(T).GetProperties())
{
if(p.Name==列)
{
return list.OrderBy(c=>c.GetType().GetProperty(p.Name).GetValue(c,null)).ToList();
}
}
退货清单;
}
然后可以使用

var sortedList = SortList<Car>(cars, "NumCreated");
var sortedList=SortList(汽车,“NumCreated”);

因为它使用反射,所以它可以用于任何对象的列表,而不必更改。

好的。switch语句、SortOrder和SortColumn枚举呢?我对此投了反对票,因为它似乎与他的问题(他文章的最后一句)没有任何关系完全可以。将
排序
更改为
OrderBy
并不能帮助他删除每个属性的所有重复代码。+1-将
字段选择器
作为方法参数发送很好。非常好的解决方案,如:)+1这可以很容易地更改为接受枚举,而不是列的字符串