The original poster said:
The Sort method throws the following exception:
System.InvalidOperationException: The comparer threw an exception. --->
System.ArgumentException: At least one object must implement IComparable.
I assume it doesn't work because the Sort method can not handle two
dimensional ArrayLists.
You are confused on two points:
- First, it doesn't work because of what the exception message told you: the
Point class doesn't implement the interface IComparable. That means your ArrayList doesn't know how to compare two points:
How does Point(1,2) compare to Point(2,1: is the first greater than, less than or equal to the second?
Second, ArrayList is just an array -- a list -- of objects. It is inherently 1-dimensional. It is an adjustable length equivalent of, say, object[].
Third, you should avoid using the non-generic collection classes, for a couple of reasons.
- They're not type-safe, and
- The generic versions are a whole lot easier to use since they're strongly typed: you don't have to downcast the contained references into the correct type.
So, given this definition of Point:
public struct Point
{
public int X { get ; set ; }
public int Y { get ; set ; }
public Point( int x , int y )
{
this.X = x ;
this.Y = y ;
}
}
You could sort your ArrayList thusly:
public class PointComparer : IComparer
{
int IComparer.Compare( object x , object y )
{
if ( x != null && !(x is Point) ) throw new ArgumentException();
if ( y != null && !(y is Point) ) throw new ArgumentException();
if ( x == null && y == null ) return 0 ; // two nulls are equals
else if ( x == null && y != null ) return -1 ; // we're collating nulls-low: change to +1 to collate nulls-high
else if ( x != null && y == null ) return +1 ; // we're collating nulls-low: change to -1 to collate nulls-high
else // both x and y are non-null
{
Point left = (Point) x ;
Point right = (Point) y ;
if ( left.Y < right.Y ) return -1 ;
else if ( left.Y > right.Y ) return +1 ;
else // ( left.Y == right.Y )
{
if ( left.X < right.X ) return -1 ;
else if ( left.X > right.X ) return +1 ;
else /* ( left.X == right.X ) */ return 0 ;
}
}
}
}
...
ArrayList listOfPoints = CreateListofPoints();
listOfPoints.Sort( new PointComparer() ) ;
Or you could use the generic collections and accomplish the same thing a whole lot more concisely:
List<Point> listOfPoints = CreateListOfPoints();
listOfPoints.Sort( (left,right) => left.Y.CompareTo(right.Y) != 0
? left.Y.CompareTo(right.Y )
: left.X.CompareTo(right.X)
) ;
List<Point>instead ofArrayList?List<point>andlist = list.OrderBy(t=>t.Y).ToList();. You shouldn't be using ArrayList anymore, now that there are nice generic collections likeList<T>.