如何按C#中的特定字段对对象列表进行排序?

mar*_*cgg 24 c# sorting

我有这门课:

public class StatInfo
{
  public string contact;
  public DateTime date;
  public string action;
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个StatInfo列表,但我不确定如何根据日期字段对其进行排序.我应该使用排序方法吗?我应该创建自己的吗?

var _allStatInfo = new List<StatInfo>();
// adding lots of stuff in it
_allStatInfo.SortByDate???
Run Code Online (Sandbox Code Playgroud)

无需编写大量代码(如果可能),最好的方法是什么?

谢谢

Ben*_*n M 61

使用LINQ:

var sortedList = _allStatInfo.OrderBy(si => si.date).ToList();
Run Code Online (Sandbox Code Playgroud)

对原始列表进行排序:

_allStatInfo.Sort(new Comparison<StatInfo>((x, y) => DateTime.Compare(x.date, y.date)));
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 15

无论如何,我看到你已经得到了答案,但......

  1. 只需将语句分成两半即可避免一些丑陋:

    Comparison<StatInfo> comparison = (x, y) => DateTime.Compare(x.date, y.date);
    _allStatInfo.Sort(comparison);
    
    Run Code Online (Sandbox Code Playgroud)

    您也可以考虑直接调用CompareTo:

    Comparison<StatInfo> comparison = (x, y) => x.date.CompareTo(y.date);
    _allStatInfo.Sort(comparison);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 你可以IComparer<T>使用我的ProjectionComparer类创建一个实现- 它是MiscUtil的一部分,我在这个答案的底部包含了一个未注释的版本.然后你写:

    _allStatInfo.Sort(ProjectionComparer<StatInfo>.Create(x => x.date));
    
    Run Code Online (Sandbox Code Playgroud)
  3. 即使你使用的是.NET 2.0,你仍然可以通过LINQBridge使用LINQ .

这是ProjectionComparer第二个答案所需的课程.前几个类实际上只是让通用类型推理更好地工作的助手.

public static class ProjectionComparer
{
    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
        (Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }

    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
        (TSource ignored, Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }

}

public static class ProjectionComparer<TSource>
{
    public static ProjectionComparer<TSource, TKey> Create<TKey>
        (Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }
}

public class ProjectionComparer<TSource, TKey> : IComparer<TSource>
{
    readonly Func<TSource, TKey> projection;
    readonly IComparer<TKey> comparer;

    public ProjectionComparer(Func<TSource, TKey> projection)
        : this (projection, null)
    {
    }

    public ProjectionComparer(Func<TSource, TKey> projection,
                              IComparer<TKey> comparer)
    {
        projection.ThrowIfNull("projection");
        this.comparer = comparer ?? Comparer<TKey>.Default;
        this.projection = projection;
    }

    public int Compare(TSource x, TSource y)
    {
        // Don't want to project from nullity
        if (x==null && y==null)
        {
            return 0;
        }
        if (x==null)
        {
            return -1;
        }
        if (y==null)
        {
            return 1;
        }
        return comparer.Compare(projection(x), projection(y));
    }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*Tao 5

为了说明 Robert C. Cartaino 的回答:

public class StatInfo : IComparable<StatInfo>
{
    public string contact;
    public DateTime date;
    public string action;

    public int CompareTo(StatInfo value)
    {
        return this.date.CompareTo(value.date);
    }
}

var _allStatInfo = new List<StatInfo>();

// this now sorts by date
_allStatInfo.Sort();
Run Code Online (Sandbox Code Playgroud)

这不是最通用的解决方案,但如果您只想按日期排序,则很好。而且,正如 Robert 所说,您仍然可以通过将 IComparer 参数传递给排序方法来覆盖默认排序。