Search code examples
c#.neticomparable

IComparable CompareTo(), How can I implement comparison on 2 different fields


I Have a class like so :

public class Incident : IComparable<Incident>
{
    public int Id { get; set; }
    public string Description { get; set; }
    public string IncidentType { get; set; }

    public int CompareTo(Incident other)
    {
        string str = other.Description;
        int ret = -1;
        if (String.Compare(Description, str, StringComparison.OrdinalIgnoreCase) < 0)
            ret = 1;
        else if (String.Compare(Description, str, StringComparison.OrdinalIgnoreCase) > 0)
            ret = -1;
        else if (String.Compare(Description, str, StringComparison.OrdinalIgnoreCase) == 0)
            ret = 0;

        return ret;
    }
}

I can sort objects of this class alphabetically based on the description field. How can I sort the class based on IncidentType field ?

I do not want to sort them on both fields simultaneously. Sometimes I want to sort incidents by Description, sometimes on IncidentType


Solution

  • If it's a typical case for you to sort either by Description or by IncidentType, you can implement different Comparers to sort on different conditions

    public class Incident: IComparable<Incident> {
      ...
    
      private IncidentTypeComparerClass: IComparer<Incident> {
        public int Compare(Incident x, Incident y) {
          if (Object.ReferenceEquals(x, y))
            return 0;
          else if (Object.ReferenceEquals(x, null))
            return -1;
          else if (Object.ReferenceEquals(null, y))
            return 1;
    
          return String.Compare(x.IncidentType, y.IncidentType, StringComparison.OrdinalIgnoreCase);
        }    
      }
    
      // Additional comparer, by IncidentType 
      public static readonly ByIncidentTypeComparer: IComparer<Incident> = new IncidentTypeComparerClass();
    
      ...
    }
    
    ...
    
    List<Incident> incidents = ...
    
    // Sort by IncidentType    
    incidents.Sort(Incident.ByIncidentTypeComparer);
    ...
    // Default sort (that's by Description)
    incidents.Sort();
    

    In case you want to sort by IncidentType only once or twice you can do it explicitly:

    List<Incident> incidents = ...
    
    incidents.Sort((x, y) => String.Compare(x.IncidentType, 
                                            y.IncidentType, 
                                            StringComparison.OrdinalIgnoreCase));