自定义排序(三个领域的IComparer)

时间:2010-12-21 16:29:33

标签: c# .net comparison

我有一个人类,有三个字段,标题,名称,性别,我想创建一个自定义排序,首先按标题排序,然后按名称排序,然后按性别升序排序:

public class SortPerson : IComparer
    {
        public int Compare(object x, object y)
        {
            (…)
        }
    }

我知道如何只针对一个变量进行比较: 但我怎么会继续三个?

public class SortPerson : IComparer
        {

int IComparer.Compare(object a, object b)
   {
      Person p1=(Person)a;
      Person p2=(Person)b;
      if (p1.Title > p2.Title)
         return 1;
      if (p1.Title < p2.Title)
         return -1;
      else
         return 0;
   }
}

非常感谢,

4 个答案:

答案 0 :(得分:33)

//Assuming all the fields implement IComparable
int result = a.field1.CompareTo(b.field1);
if (result == 0)
  result = a.field2.CompareTo(b.field2);
if (result == 0)
  result = a.field3.CompareTo(b.field3);
return result;

答案 1 :(得分:5)

我不知道你对比较器有什么用处,但也许你可以使用“order by”LINQ语句来代替比较器,它允许按各种字段排序:

var orderedListPersons =
    from p in listPersons
    orderby p.Title, p.Name, p.Gender
    select person;

将以您想要的方式订购listPersons。您也可以使用LINQ OrderBy和ThenBy方法使用不同的语法:

var orderedlistPersons = listPersons.OrderBy(p => p.Title).ThenBy(p => p.Name).ThenBy(p => p.Gender);

答案 2 :(得分:0)

按优先顺序一次按一个字段排序,如果前一个字段比较结果为0(字段相等),则仅继续到下一个字段。有关2字段排序的示例,请参阅以下内容。

http://csharp.2000things.com/2010/10/30/135-implementing-icomparable-to-allow-sorting-a-custom-type/

答案 3 :(得分:0)

一种方法是实现这样的接口。

public class Person : IComparer<Person>
{
    public string Titel { get; set; }

    int IComparer<Person>.Compare(Person x, Person y)
    {
        if (x is null)
            throw new ArgumentNullException(nameof(x));
        if (y is null)
            throw new ArgumentNullException(nameof(y));

        return x.Titel.CompareTo(y.Titel);                      
    }
}

有时候,虽然您可能有一个“更多控制权”,但您还是希望如何进行排序。当然,您可以使用linq,但是这样就不得不浪费列表垃圾分配的速度,并且在实现IComparer接口时确实不难做到。

看看下面的示例,您会发现可以根据需要组合任意多个属性。

public class Person : IComparable<Person>, IComparer<Person>
{
    public string Titel { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime? SomeOptionalValue { get; set; }

    int IComparer<Person>.Compare(Person x, Person y)
    {       
        return (x as IComparable).CompareTo(y);
    }

    int IComparable<Person>.CompareTo(Person other)
    {
        if (other is null)
            throw new ArgumentNullException(nameof(other));
        int result = this.Titel.CompareTo(other.Titel);

        //chain the other properties in the order you'd like to
        //have them sorted. 
        if (result == 0)
            result = this.FirstName.CompareTo(other.FirstName);

        if (result == 0)
            result = this.LastName.CompareTo(other.LastName);

        //use optional values as well as call the compare implementation on a class
        if (result == 0 && SomeOptionalValue.HasValue && other.SomeOptionalValue.HasValue)
            result = DateTime.Compare(this.SomeOptionalValue.Value, other.SomeOptionalValue.Value);

        return result;
    }
}