IComparable CompareTo(),如何在2个不同的字段上实现比较

时间:2014-02-24 13:55:02

标签: c# .net icomparable

我有一个这样的课程:

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;
    }
}

我可以根据描述字段按字母顺序对该类的对象进行排序。 如何根据IncidentType字段对类进行排序?

我不想同时在两个字段上对它们进行排序。 有时我想按Description对事件进行排序,有时候在IncidentType

5 个答案:

答案 0 :(得分:3)

您可以在单独的类中实现IComparer<T>,并在排序元素时使用此比较器:

public class IncidentComparer : IComparer<Incident>
{
    public int Compare(Incident x, Incident y)
    {
        return x.IncidentType.CompareTo(y.IncidentType);
    }
}

例如,如果您有这样的列表,则可以使用比较器:

List<Incident> incidents = new List<Incident>();
...
incidents.Sort(new IncidentComparer());

或者您可以改为使用LINQ

incidents = incidents.OrderBy(x => x.IncidentType).ToList();

答案 1 :(得分:3)

如果您要按DescriptionIncidentType进行排序,则可以实施不同的比较器以对不同条件进行排序

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();

如果您想按IncidentType排序一次或两次,您可以显式

List<Incident> incidents = ...

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

答案 2 :(得分:1)

您可以返回一个早于函数结尾的值,因此如果ret为0,则可以使用if语句检查,如果为真,则返回ret。如果不是这样,将跳过if语句,并评估函数的其余部分。例如:

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 = String.Compare(str, Description, StringComparison.OrdinalIgnoreCase);
        if (ret != 0)
            return ret;
        str = other.IncidentType;
        ret = String.Compare(str, IncidentType, StringComparison.OrdinalIgnoreCase);
        return ret;
    }
}

将按说明排序,如果说明相同,则它将按IncidentType排序。如果您想先按IncidentType排序,请切换两个。

答案 3 :(得分:0)

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

        return ret;
    }

请记住,这只是IncidentType上的普通字符串比较。您可能需要在此处引入更复杂的业务规则。

答案 4 :(得分:0)

要进行排序,例如:

List<Indicent> listIncident = new List<Incident>(); 

//This to sort based on the incidentType
listIndicent = listIncident.OrderBy(x => x.IncidentType).ToList();

//This to sort based on the description
listIndicent = listIncident.OrderBy(x => x.Description).ToList();

//This to sort based on two
listIndicent = listIncident.OrderBy(x => x.Description).ThenBy(x => x.IncidentType).ToList();