Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialMoses Wynn
20,461 PointsHow do I implement the IComparer interface?
In the C# Collections Course in the Sorting Lists video the following is stated:
"To tell the sort method how to sort, we can create a class that implements the IComparer interface. It has a single method, and it takes two parameters of the same type...
...The compare method works just like the CompareTo method in the IComparable interface. We can pass an instance of this object to the sort method and it will call the compare method in order to determine the order of the objects in the list. We won't implement the IComparer interface here. Instead, I'm going to leave this as an exercise for you to practice implmenting generic interfaces."
I am attempting to implement the IComparer interface on the Square class below, but when calling the sort method on the list I receive the following error:
"System.InvalidOperationException
HResult=0x80131509
Message=Failed to compare two elements in the array.
Source=mscorlib
StackTrace:
at System.Collections.Generic.ArraySortHelper1.Sort(T[] keys, Int32 index, Int32 length, IComparer
1 comparer)
at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer1 comparer)
at System.Collections.Generic.List
1.Sort(Int32 index, Int32 count, IComparer1 comparer)
at System.Collections.Generic.List
1.Sort()
at Collections.Program.Main() in C:\Users\a683040\source\repos\Collections\Collections\Program.cs:line 35
Inner Exception 1: ArgumentException: At least one object must implement IComparable."
My code is below:
Square.cs
using System;
using System.Collections.Generic;
namespace Collections
{
class Square : IComparer<Square>
{
public int Length;
public int Width;
public int Area;
public Square(int length, int width)
{
Length = length;
Width = width;
Area = length * width;
}
public int Compare(Square x, Square y)
{
if (x.Area.CompareTo(y.Area) != 0)
{
return x.Area.CompareTo(y.Area);
}
else if(x.Length.CompareTo(y.Length) !=0 )
{
return x.Length.CompareTo(y.Length);
}
else if (x.Width.CompareTo(y.Width) !=0 )
{
return x.Width.CompareTo(y.Width);
}
else
{
return 0;
}
}
}
}
Program.cs
using System;
using System.Collections.Generic;
namespace Collections
{
class Program
{
static void Main()
{
List<Square> squares = new List<Square>
{
new Square(1,2),
new Square(3,4),
new Square(2,2),
new Square(3,3),
new Square(2,3)
};
//squares.Sort(); <Incorrect line
squares.Sort(squares[0]); //<Correct line as provided in comments of "Best Answer" by Steven Parker
foreach (Square square in squares)
{
Console.WriteLine($"This box has a length of {square.Length} and a width of {square.Width}.");
}
Console.ReadLine();
}
}
}
1 Answer
Steven Parker
231,248 PointsJudging from the error messages, it sounds like you must also implement IComparable
and create a "CompareTo" method.
Moses Wynn
20,461 PointsMoses Wynn
20,461 PointsRight, but in the video he made it sound like we should be calling the sort method on the list by implementing IComparer interface with the corresponding Compare method instead of the IComparable interface and the CompareTo method.
Steven Parker
231,248 PointsSteven Parker
231,248 PointsBut ".sort()" falls back on
IComparable
if no comparer argument is provided. So if you don't want to implement it also, provide an instance of "Square" (either a new or existing one) to use as a comparer when you call it:squares.Sort(squares[0]);
Moses Wynn
20,461 PointsMoses Wynn
20,461 PointsThat did it! Thank you very much!