linq 如何按继承类的DateTime属性对List进行排序?

2izufjch  于 2023-09-28  发布在  其他
关注(0)|答案(3)|浏览(109)

考虑以下情况。我有一个基类Measurement和几个派生类(e.例如AdditionalMeasurementSpecialMeasurement),它们继承自Measurement

class Measurement {
   public DateTime TimeStamp { get; set; }
}

class AdditionalMeasurement : Measurement {
   public DateTime PurchaseDate { get; set; }
}

class SpecialMeasurement: Measurement {
   public DateTime PrescriptionDate { get; set; }
}

如果列表中的项的类型为AdditionalMeasurement x PurchaseDate,并且项的类型为SpecialMeasurement x PrescriptionDate,那么我如何按照默认值Measurement.TimeStamp降序排序List<Measurement>(=对于所有其他派生类)?
显然,我下面的尝试不起作用,但希望能显示出这个想法。

List<Measurement> measurements = new List<Measurement>() { ... };
measurements.OrderByDescending(m =>
{
    if (m is AdditionalMeasurement additionalMeasurement)
    {
        return additionalMeasurement.PurchaseDate;
    }
    else if (m is SpecialMeasurement specialMeasurement)
    {
        return specialMeasurement.PrescriptionDate;
    }
    else
    {
        return m.TimeStamp;
    }
});
soat7uwm

soat7uwm1#

经典的OOP方法是让每个类为自己定义/覆盖其排序标准:

using System;

class Measurement {
   public DateTime TimeStamp { get; set; }

   public virtual DateTime SortDate => this.TimeStamp;
}

class AdditionalMeasurement : Measurement {
   public DateTime PurchaseDate { get; set; }
    
    public override DateTime SortDate => this.PurchaseDate;
}

class SpecialMeasurement: Measurement {
   public DateTime PrescriptionDate { get; set; }
    
    public override DateTime SortDate => this.PrescriptionDate;
}

                    
public class Program
{
    public static void Main()
    {
        var measurements = new List<Measurement>() { };

        var ordered = measurements.OrderBy(m => m.SortDate).ToList();

    }
}

您的特定问题可能是OrderBy返回一个有序的Enumerable,它不对现有列表进行排序。您的调用没有使用返回值,这表明您可能没有意识到这一点。提高编译器的警告级别,这应该是一个编译器警告。
您可以使用List<T>Sort方法对列表进行排序,然后可以将要排序的日期逻辑放在Comparer类中。如果您有许多不同的排序逻辑,这可能会有所帮助。

ohtdti5x

ohtdti5x2#

如果你不想像nvoigt建议的那样改变类,下面的代码更短,正确地使用了ToList,并将结果分配给原始列表:

measurements = measurements.OrderByDescending(m => m switch
{
    AdditionalMeasurement additionalMeasurement => additionalMeasurement.PurchaseDate,
    SpecialMeasurement specialMeasurement => specialMeasurement.PrescriptionDate,
    _ => m.TimeStamp
}).ToList()

所以你的代码的问题主要是你没有使用从OrderByDescending返回的IEnumerable<Measurement>来创建一个新的列表(ToList)。

im9ewurl

im9ewurl3#

您可以尝试使用TimeStamp作为默认比较器对列表进行排序,然后反转数组以按降序获得Measurement对象的列表。

//sort the objects in the list ascendingly
list.Sort((x,y)=> x.TimeStamp.CompareTo(y.TimeStamp));
//reverse the order of Measurement objects
list.Reverse();

相关问题