У меня была такая же проблема, что и я, я упорядочил порядок библиотек в последовательности, например, были java.lang.NullPointerException и javacard.lang.NullPointerException. Я сделал первую в качестве библиотеки по умолчанию, и если вам нужно использовать другую, вы можете явно указать полное имя класса.
Передо мной нет компилятора для проверки, но я думаю что-то вроде:
x.OrderBy(i => i == null).ThenBy(i => i)
Как сказал Джон, вам нужно определить свой собственный Comparer, реализующий IComparer
. Вот как ваш метод Compare
в пользовательском компараторе хотел бы сохранить null
в конце.
public int Compare(Object x, Object y)
{
int retVal = 0;
IComparable valX = x as IComparable;
IComparable valY = y as IComparable;
if (valX == null && valY == null)
{
return 0;
}
if (valX == null)
{
return 1;
}
else if (valY == null)
{
return -1;
}
return valX.CompareTo(valY);
}
Вы можете написать свой собственный компаратор, который делегирует существующий для ненулевых значений, но всегда сортирует нули в конце. Примерно так:
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);
}
}
РЕДАКТИРОВАТЬ: Несколько проблем с этим подходом:
Во-первых, он плохо работает с анонимными типами; вам может потребоваться отдельный метод расширения, чтобы он работал хорошо. Или используйте ответ Кена :)
Что еще более важно, он нарушает контракт IComparer
, который указывает, что нули должны быть первыми. Лично я считаю, что это ошибка в спецификации IComparer
- возможно, она должна определять, что компаратор должен обрабатывать нули, но он должен не указать, идут ли они первыми или последними ... это делает такие требования (которые совершенно разумны) невозможными для выполнения с такой точностью, как мы могли бы пожелать, и имеет всевозможные неудобные разветвления для таких вещей, как реверсивный компаратор. Можно было бы ожидать, что такая вещь полностью изменит порядок следования, но, согласно спецификации, она все равно должна поддерживать нули в начале: (
Я не думаю, что видел какие-либо реализации сортировки .NET, которые на самом деле полагаются на это , но об этом определенно стоит знать.