1.2 ICompare和IComparable

发布时间 2023-10-27 13:13:41作者: 闵书涵

C#排序和比较的实现

1.IComparable/IComparable

假设定义了一个数据,数据存放在List集合中,现在需要按 自己设想的排序规则来排序

static void Main(string[] args)
{
    Person p1 = new Person("Fuor", 28);
    Person p2 = new Person("Adain", 58);
    int r = p1.CompareTo(p2);
    Person p3 = new Person("Colo", 38);
    List<Person> plist = new List<Person>();
    plist.Add(p1);
    plist.Add(p2);
    plist.Add(p3);
    plist.Sort();
}
class Person 
{

    public string Name { get; set; }
    public int Age { get; set; }

    public Person() { }
    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }
}

如下图,直接报错,无法比较,因为Sort不知到需要按照什么规则来排序

//用 数据类型 实现接口IComparable,并在实现方法Compare(obj o)中定义好规则即可
class Person : IComparable<Person>
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    public Person() { }
    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }
    public int CompareTo(Person p)
    {
        if (this.Age == p.Age)
        {
            return 0;
        }
        else if (this.Age < p.Age)
            return -1;
        else
            return 1;
    }
}

//未实现IComparable接口时候,此方法报错,无法使用
Person p1 = new Person("Fuor", 28);
Person p2 = new Person("Adain", 58);
//实现接口后,可以调用CompareTo() 来比较两个对象
int result = p1.CompareTo(p2);

public int CompareTo(object obj)
{
   Person p = obj as Person;
    if (this.Age == p.Age)
    {
        return 0;
    }
    else if (this.Age < p.Age)
        return -1;
    else
        return 1;
}

2.ICompare/ICompare

问题2,虽然有默认的排序了,但是在某些特定的情景下,我需要采用其他的排序规则呢?

此时ICompare就出现了,所以ICompare/ICompare 其实就是解决特定情况 下,用户除了默认的排序外还需要特殊的排序规则,此时就需要自定义一个新的排序规则

static void Main(string[] args)
{
    Person p1 = new Person("Fuor", 28);
    Person p2 = new Person("Adain", 58);

    Person p3 = new Person("Colo", 38);
    List<Person> plist = new List<Person>();
    plist.Add(p1);
    plist.Add(p2);
    plist.Add(p3);

    PersonCompare personCompare = new PersonCompare();
    personCompare.Compare(p1, p2);

    //指定自定义的比较器 来排序
    plist.Sort(0, plist.Count, personCompare);//如果是需要指定 不是默认比较实现的 比较器

    Console.WriteLine();
    Console.ReadKey();
}
//继承ICompare 需要实现Compare方法,然后将比较器传入需要使用的地方即可
class PersonCompare : IComparer<Person>//ICompare<T> 可以限定传入的类型
{
    public int Compare(Person x, Person y)
    {
        if (x.Name.First() > y.Name.First())
            return 1;
        else if (x.Name.First() < y.Name.First())
            return -1;
        else
            return 0;
    }
}