List <T>. Sorting sort errors is incorrect.
I have a list of objects, some of which may be empty. I want it to be sorted by some property with nullat the end of the list. However, the method List<T>.Sort()seems to put nullin at the beginning no matter what the comparator returns. This is a small program that I used for testing:
class Program
{
class Foo {
public int Bar;
public Foo(int bar)
{
Bar = bar;
}
}
static void Main(string[] args)
{
List<Foo> list = new List<Foo>{null, new Foo(1), new Foo(3), null, new Foo(100)};
foreach (var foo in list)
{
Console.WriteLine("Foo: {0}", foo==null?"NULL":foo.Bar.ToString());
}
Console.WriteLine("Sorting:");
list.Sort(new Comparer());
foreach (var foo in list)
{
Console.WriteLine("Foo: {0}", foo == null ? "NULL" : foo.Bar.ToString());
}
Console.ReadKey();
}
class Comparer:IComparer<Foo>
{
#region Implementation of IComparer<in Foo>
public int Compare(Foo x, Foo y)
{
int xbar = x == null ? int.MinValue : x.Bar;
int ybar = y == null ? int.MinValue : y.Bar;
return ybar - xbar;
}
#endregion
}
}
Try it yourself: the sorted list is printed as
Foo: NULL
Foo: NULL
Foo: 100
Foo: 3
Foo: 1
nullFirst, although they are compared as int.Minvalue. Is the method a mistake or what?
+3
5 answers
Assume that xis nulland yis equal to 1.
int xbar = x == null ? int.MinValue : x.Bar;
int ybar = y == null ? int.MinValue : y.Bar;
return ybar - xbar;
, 1 - int.MinValue. , , null 1.
.
public int Compare(Foo x, Foo y)
{
int xbar = x == null ? int.MinValue : x.Bar;
int ybar = y == null ? int.MinValue : y.Bar;
return ybar.CompareTo(xbar);
}
( .)
+12
, , , .
, . :
- FooCompare Foo, x y. null.
- IComparer.Compare(x, y) , x y , , y x, , y x. .
- x y , .
- , - , .
- , Bar.
, , :
// FooCompare takes two references to Foo, x and y. Either may be null.
// +1 means x is larger, -1 means y is larger, 0 means they are the same.
int FooCompare(Foo x, Foo y)
{
// if x and y are both null, they are equal.
if (x == null && y == null) return 0;
// if one is null and the other one is not then the non-null one is larger.
if (x != null && y == null) return 1;
if (y != null && x == null) return -1;
// if neither are null then the comparison is
// based on the value of the Bar property.
var xbar = x.Bar; // only calculate x.Bar once
var ybar = y.Bar; // only calculate y.Bar once
if (xbar > ybar) return 1;
if (ybar > xbar) return -1;
return 0;
}
// The original poster evidently wishes the list to be sorted from
// largest to smallest, where null is the smallest.
// Reverse the polarity of the neutron flow:
int Compare(Foo x, Foo y)
{
return FooCompare(y, x);
}
; , . .
+13