如何在LINQ中进行自定义排序,最后总是使用null?

Jer*_*ryk 16 c# linq

我需要按升序或降序对字符串或数字的内存列表进行排序.但是,列表可以包含空值,并且所有空值必须出现在数字或字符串之后.

那是输入数据可能是:

1, 100, null, 5, 32.3

上升的结果将是

1, 5, 32.3, 100, null

下降列表将是

100, 32.3, 5, 1, null

关于如何使这项工作的任何想法?

Ken*_*Ken 42

我面前没有编译器来检查,但我想的是:

x.OrderBy(i => i == null).ThenBy(i => i)
Run Code Online (Sandbox Code Playgroud)

  • 很好......这是一个非常甜蜜的方法.如果可以的话,我会不止一次投票 (3认同)

Jon*_*eet 6

你可以写你自己的比较器委托给现有的一个非空值,但总是在最后排序空值.像这样的东西:

public class NullsLastComparer<T> : IComparer<T>
{
    private readonly IComparer<T> proxy;

    public NullsLastComparer(IComparer<T> proxy)
    {
        this.proxy = proxy;
    }

    public override int Compare(T first, T second)
    {
        if (first == null && second == null)
        {
            return 0;
        }
        if (first == null)
        {
            return 1;
        }
        if (second == null)
        {
            return -1;
        }
        return proxy.Compare(first, second);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:这种方法的一些问题:

首先,它不能很好地与匿名类型一起使用; 您可能需要一个单独的扩展方法才能使其正常工作.或者使用Ken的答案:)

更重要的是,它违反了IComparer<T>合同,该合同规定了空值应该是第一个.现在我个人觉得,这是在一个错误的IComparer<T>规范-它也许应该定义的比较器应处理空值,但应指定他们是否来第一个或最后...它使这样的要求(这是完全合理的)不可能尽可能干净地满足我们的要求,并且对于像逆转比较器这样的事情有各种各样的尴尬后果.你期望这样的事情完全颠倒排序,但根据规范,它仍然应该在开始时保持空值:(

我认为我没有看到任何实际依赖于此的.NET排序实现,但它绝对值得注意.