search
Japanese Chinese Nederlands Espanol Italiano Deutsch Francais Twitter Rss Feeds
MicrosoftArticlesForumsFAQs
C# .NET
VB.NET
Visual Studio .NET
ADO.NET
Xml / Xslt
VB 6.0
.NET CF
GDI+
LINQ
Deployment
Security
FoxPro
Silverlight / WPF
Entity Framework
RIA Services

Web ProgrammingArticlesForumsFAQs
JavaScript
ASP
ASP.NET
Web Services

Non-MicrosoftArticlesForumsFAQs
NHibernate
Perl
PHP
Ruby
Java
Linux / Unix
Apple
Open Source

DatabasesArticlesForumsFAQs
SQL Server
Access
Oracle
MySQL
Other Databases

OfficeArticlesForumsFAQs
Excel
Word
Powerpoint
Outlook
Publisher
Money

Operating SystemsArticlesForumsFAQs
Windows 7
Windows Server
Windows Vista
Windows XP
Windows Update
MAC
Linux / UNIX

Server PlatformsArticlesForumsFAQs
BizTalk
Site Server
Exhange Server
IIS

Graphic DesignArticlesForumsFAQs
Macromedia Flash
Adobe PhotoShop
Expression Blend
Expression Design
Expression Web

OtherArticlesForumsFAQs
Subversion / CVS
Ask Dr. Dotnetsky
Active Directory
Networking
Uninstall Virus
Job Openings
Product Reviews
Search Engines
Resumes

 

Custom Sorting With IComparable and IComparer


By Sadhana G
Printer Friendly Version
View My Articles
119 Views
    

Sometimes, you want to be able to sort objects on a number of different fields. For example, employees can be sorted by their name, years of service, pay rate; or blog posts by the date they were posted, their status, number of comments, the author. It's really easy to offer all these sorting methods. Best of all you don't have to write too much code.


Default Sorting

Suppose we have a Politician class:


public class Politician
{
private string ssn;
private string name;
private int powerIndex;
private int voterBaseIndex;
private int suckitudeIndex;

public string SSN
{
get { return this.ssn; }
}

public string Name
{
get { return this.name; }
}

public int PowerIndex
{
get { return this.powerIndex; }
}

public int VoterBaseIndex
{
get { return this.voterBaseIndex; }
}

public int SuckitudeIndex
{
get { return this.suckitudeIndex; }
}
}

We want to allow the users to sort by name, powerIndex, voterBaseIndex, or the suckitudeIndex. We feel that people generally want to sort the politicians by their suckitudeIndex. So we're going to have the default sorting method sort by the suckitudeIndex while giving users the option of sorting by various other indices, too.

Default Sorting: IComparable

To tell .NET how to sort objects by default, all we need to do is inherit from the IComparable interface:

public class Politician : System.IComparable<Politician>

You notice that we're using the generic interface, which takes in an object of the type we're interested in, instead of the normal IComparable interface, which takes in whatever object.

The IComparable interface has a single method that we need to implement: CompareTo; the implementation is straight-forward:


public int CompareTo(Politician politician)
{
// NULL is considered to be smaller than
// any other value.
if (politician == null)
{
return 1;
}

else if (this.suckitudeIndex < politician.suckitudeIndex)
{
return -1;
}

else if (this.suckitudeIndex == politician.suckitudeIndex)
{
return 0;
}

else { return 1;
}
}

Sorting by Power Index: IComparer

A class can sort by any number of fields or any combination of fields. We do this by creating classes that implement the IComparer.

For example:


public class PowerIndexComparer : System.Collections.Generic.IComparer<Politician>
{
public int Compare(Politician first, Politician second)
{
if (first == null & second == null)
{
return 0;
}

else if (first == null)
{
return -1;
}

else if (second == null)
{
return 1;
}

else if (first.powerIndex < second.powerIndex)
{
return -1;
}

else if (first.powerIndex == second.powerIndex)
{
return 0;
}

else { return 1;
}
}
}

And when you want to sort politicians by the power index, simply pass along the IComparable object to the sort method:

politicians.Sort(new PowerIndexComparer());

Usually, I create the IComparable classes as private classes within the main class. For example, the PowerIndexComparer would be declared as a private class within the Politician class. This was how I saw it done in one of the books I read. It makes sense, because all comparer classes aren't independent/full-fledged classes but rather part of the Politician class. So the way this would work:


public class Politician : System.IComparable<Politician>
{
private class PowerIndexComparer : System.Collections.Generic.IComparer<Politician>

{
public int Compare(Politician first, Politician second)
{
if (first == null & second == null)
{
return 0;
}

else if (first == null)
{
return -1;
}

else if (second == null)
{
return 1;
}

else if (first.powerIndex < second.powerIndex)
{
return -1;
}

else if (first.powerIndex == second.powerIndex)
{
return 0;
}

else { return 1;
}
}
}

public static System.Collections.Generic.IComparer<Politician> PowerIndexSorter
{
get { return new PowerIndexComparer(); }
}
}

So when you want to sort by power index:

politicians.Sort(Politician.PowerIndexSorter);
Original article here


button
Article Discussion: Custom Sorting With IComparable and IComparer
Sadhana G posted at Wednesday, October 18, 2006 10:12 AM
Original Article
 

Compare or CompareTo
Falaque The DangerDev replied to Sadhana G at Tuesday, February 10, 2009 1:44 AM
Hi,
 I think IComparable have only one method that is CompareTo. Above given example will not work.
 
 modified code:
 
 CompareTo(Politician other)
 {
    Politician first=this;
    Politician second=othere;
    
    //your code
 }